标签: com-interop

如何在某些条件满足时在运行时在c ++中导入tlb和命名空间?

通常我们在程序的开头导入一个tlb文件

#include < stdio.h >
#import " sql.tlb "
Run Code Online (Sandbox Code Playgroud)

但是当我在程序中间满足某些条件时,我需要导入一个tlb文件

我怎样才能做到这一点.加载dll有LoadLibrary()但是加载tlb我可以使用LoadLibrary().

因为tlb是使用.dll生成的?

c++ com com-interop visual-c++

2
推荐指数
1
解决办法
2755
查看次数

使用Midl从.idl创建.tlb"期望类型规范"的问题

我和被称为COM Interop的野兽长期相遇...

我目前正在尝试从OLE/COM对象查看器生成的.idl文件生成.tlb.但是,当尝试运行Midl.exe来编译它时,我收到一个错误:

.\Sim.API.IDL(236) : error MIDL2025 : syntax error : expecting a type s
pecification near "ImportFileStatus"
Run Code Online (Sandbox Code Playgroud)

我的.idl文件超过1000行,所以我不特别想在这里发帖,我相信感兴趣的部分是:

typedef [uuid(980B172E-19C1-389A-BB74-29A54737C5B4), version(1.0)    ,
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "Sim.API.ImportFileResult")    
 ]
 struct tagImportFileResult {

  ImportFileStatus _status;

  LPSTR _message;
 } ImportFileResult;
Run Code Online (Sandbox Code Playgroud)

然后几行......

 typedef [uuid(A4B9A0FF-A2D4-3EC5-AB7E-69311B9122C8), version(1.0)    ,
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "Sim.API.ImportFileStatus")    
 ]
 enum {
  ImportFileStatus_Success = 0,
  ImportFileStatus_VersionMismatch = 1,
  ImportFileStatus_Failure = 2
 } ImportFileStatus;
Run Code Online (Sandbox Code Playgroud)

我有一种感觉,应该尊重这些以修复类型规范错误.但是,如果我这样做,我会遇到一个新问题.

midl\oleaut32.dll : warning MIDL2368 : error generating type library, ignored :
Could not set UUID : tagImportFileResult (0x800288C6)
Run Code Online (Sandbox Code Playgroud)

我对idl格式非常不熟悉,并且使用midl.exe,也许我正在做的事情有些明显错误?

一如既往的任何帮助将不胜感激:)

com idl com-interop typelib midl

2
推荐指数
1
解决办法
3396
查看次数

将类似索引器的属性暴露给COM

我有现有的COM接口.我不想创建一个将新接口公开为COM(带有新GUID)的.net程序集,但接口的结构必须相同.

如何创建一个公开此接口的.net类(C#)?

[
  odl,
  uuid(1ED4C594-DDD7-402F-90DE-7F85D65560C4),
  hidden,
  oleautomation
]
interface _IFlashPhase : IUnknown {

    [propget]
    HRESULT _stdcall ComponentName(
                    [in] short i, 
                    [out, retval] BSTR* pVal);
    [propput]
    HRESULT _stdcall ComponentName(
                    [in] short i, 
                    [in] BSTR pVal);
    [propget]
    HRESULT _stdcall ComponentMolePercent(
                    [in] short i, 
                    [out, retval] double* pVal);
    [propput]
    HRESULT _stdcall ComponentMolePercent(
                    [in] short i, 
                    [in] double pVal);
    [propget]
    HRESULT _stdcall ComponentFugacity(
                    [in] short i, 
                    [out, retval] double* pVal);
    [propput]
    HRESULT _stdcall ComponentFugacity(
                    [in] short i, 
                    [in] double pVal);

};
Run Code Online (Sandbox Code Playgroud)

c# idl com-interop

2
推荐指数
1
解决办法
1006
查看次数

COM互操作传递错误的指针,只有一个字节的数据

我在使用COM传递指向本机代码的指针时遇到问题.我想在托管(C#)代码中构建一个字节数组,并将该数组传递给本机(C++)代码.我正在处理托管代码方面,我的同事拥有本机方面.请注意,我在托管方面更强大,而且我几乎一直在使用COM对象.

COM签名(简化)看起来像这样:

unsafe void DoSomething([In] byte* buffer, [In] uint length)
Run Code Online (Sandbox Code Playgroud)

我称之为:

var arr = File.ReadAllBytes(@"c:\temp\foo.bar");
fixed (byte* p = arr)
{
    // let's see what we're actually pointing at
    IntPtr ip = new IntPtr(p);
    Console.WriteLine(ip.ToInt32().ToString("x"));

    interop.DoSomething(p, arr.Length);
}
Run Code Online (Sandbox Code Playgroud)

在托管端调试,我看到打印出来的内存位置的数据(使用Visual Studio的内存视图).当我调试非托管端时,我也在该位置看到了正确的数据.但是,指针并没有指向正确的位置!它指向一个完全不同的内存位置.该位置包含我的数据的正确的第一个字节,但其余部分包含垃圾.然后,当然,发生了许多奇妙的崩溃.

所以,例如,我看到:

  • 管理方:指针(p)为0x1234567,0x1234567处的内存包含我文件的内容.
  • unmanaged side:pointer(buffer)是0x5678901,该位置的内存的第一个字节包含我文件的第一个字节,其余是垃圾.内存0x1234567包含我的文件的内容.

我也试过自动封送:

void DoSomething([In] [MarshalAs(UnmanagedType.LPArray,
                                 ArraySubType = UnmanagedType.U1)]
                      byte[] buffer,
                 [In] uint length)
Run Code Online (Sandbox Code Playgroud)

...在管理端使用直字节数组; 同样的结果.

我已经尝试分配内存Marshal.AllocHGlobal,将数据复制到其中Marshal.Copy并将结果传递IntPtr给a byte*.结果相同.

我到底错过了什么?

这是一个32位进程.我尝试过小型(300B)和大型(10MB)缓冲区大小.C#3.5,VS 2010.

c# c++ com com-interop

2
推荐指数
1
解决办法
1414
查看次数

如何将函数返回值编组到非托管dll

我有一个用C#编写的dll,并且暴露给COM.我在构建器中使用dll ...我可以实例化该类,但是在编译C#方法调用的返回值时遇到了问题.

C#

public string GetValue([MarshalAs(UnmanagedType.LPWStr)] string key)
{
   return "value";
}
Run Code Online (Sandbox Code Playgroud)

导入到构建器中的已翻译函数:

virtual HRESULT STDMETHODCALLTYPE GetValue(LPWSTR key/*[in]*/, 
                                           BSTR* pRetVal/*[out,retval]*/) = 0;
Run Code Online (Sandbox Code Playgroud)

我对C++知之甚少.'key'参数传递得很好,因为我能够在参数上使用'MarshalAs'属性,但我要么不知道如何为返回值声明它,要么不知道如何调用在C++方面的功能(我尝试了几件事,只是猜测).

更新:好的,我只是通过采取Anton的例子并根据Hans的评论尝试修改来解决问题.Antons的回答正如他所展示的那样,但由于对内存管理问题的关注,我最终没有在C#中应用return属性,而C++代码调用函数如下:

BSTR result;
obj->GetValue(key, &result);
SysFreeString(key);
SysFreeString(result);
Run Code Online (Sandbox Code Playgroud)

我希望我可以赞扬这两个答案,帮助我解决这个问题,他们都必须向我提供我需要的信息.

c# c++ com com-interop marshalling

2
推荐指数
2
解决办法
9580
查看次数

是否有内置方法将HRESULT表示为winerror.h常数(例如E_FAIL)?

在我的C#代码中,我希望能够记录COMExceptions,以便不仅输出HRESULTs的十六进制表示形式(例如0x80004005),而且输出相应的WinError.h定义符号(例如E_FAIL)。

如果我调用ToString()异常引用,则只有十六进制表示形式。

是否有一种内置方法来获取对象内部值的类似E_FAIL人类可读的常量?HRESULTCOMException

.net c# com com-interop error-code

2
推荐指数
1
解决办法
821
查看次数

Microsoft Interop Word Automation的DCOM配置设置

Microsoft Office Interop Word用来使用C#生成文档.为了使文档生成工作,应该有一个在进入"Microsoft Office Word 97 - 2003 Document"Dcom Config Settings为如下所示:

在此输入图像描述

首次安装Microsoft Office时,Local Path下面General Tab有正确的路径.如果我然后将计算机加入域,然后使用域用户重新启动系统,则Local Path变为空白,应用程序不会生成文档并出错.

即使我首先将计算机加入域,然后使用域用户登录然后安装Microsoft Office,Local Path首先显示正确,然后在重新启动后再次变为空白.同时,在同一时间,如果我登录Local User时,Path仍然存在.

是什么导致价值Local Path变为空白?

所有这些设置都在虚拟机上,并且自动化一词在域帐户上工作,因为我看到它在加入域的物理机器上工作.

UPDATE: What my application is doing:
Run Code Online (Sandbox Code Playgroud)

我的应用程序中有4-5个组件.

第一个是VSTO Word AddIn,它与Microsoft Word集成,我们在其中创建包含一些也保存在数据库中的表达式的新文档.表达式上也有条件,它们也可以嵌套.表达式包含XSD文件中的架构元素,这些元素保存在数据库中.创建此类文档后,其WordML将保存在数据库中.这一切都在VSTO AddIn中完成.

第二个是Web服务,它从另一个组件接收输入xml,该组件确认上面的XSD,架构元素嵌入到通过VSTO addIn创建的文档中的表达式中.此Web服务检查验证和其他几项任务.然后,它从数据库中获取相应的Word文档的WordML中,并将其传递到使用它的API,遍历它递归来替换输入XML其实际值的架构元素的话语互操作.然后,将WordML作为word文档保存到文件中.

这也会在保存文档之前将模板附加到文档中.它使用Word Interop的SaveAs功能将文件另存为PDF.

更新:我又通过我的完整的应用程序不见了,才知道我们被解析的Office Open XML(例如用于输送输入到Word文档)做的所有的事情,但是,我们使用的是Word自动化做的唯一的事情是以下:

  1. 使用Word Interop将生成的WordML保存为Word格式文件之一.
  2. 将生成的WordML导出为PDF文件.
  3. 将多个WordML合并到单个Word文档文件中.
  4. 为它获取XML.

所有这四个代码如下所示,仅包含相关的代码部分:

Microsoft.Office.Interop.Word.Document wordDocument = null;
object templateName = "templateFile.dotm";
wordDocument = this.WordApplication.Documents.Add(ref …
Run Code Online (Sandbox Code Playgroud)

.net c# dcom com-interop office-interop

2
推荐指数
1
解决办法
8666
查看次数

VB6针对并排汇编进行编译

我有一个用C#编写的DLL,并设置为COM可见性.我将它设置为并排组件,并且可以将应用程序成功部署到客户端PC免费注册.我的问题与开发PC有关.是否可以在类似的免注册庄园中针对DLL进行编译,或者是否需要在开发机器上进行注册?我已经尝试通过Project -> References菜单直接添加DLL 并收到错误,指出"无法添加对特定文件的引用".DLL与.vbp文件位于同一目录中,我尝试添加DLL,无论是否存在客户端应用程序清单.

vb6 com com-interop side-by-side regfreecom

2
推荐指数
1
解决办法
413
查看次数

使用.NET Core在Mac OSX上进行Office(Excel)COM互操作?

我为一个目前致力于在C#/。NET中创建Windows桌面应用程序的团队工作,该应用程序通过Office COM Interop与Microsoft Excel的本地用户实例进行交互。我目前负责指定新产品,但是有人告诉我,除非该应用程序可以在Mac和Windows上运行,否则该项目将无法继续进行-也就是说,我们必须能够生产Mac版本的应用程序可以本机安装在OSX上并与Microsoft Excel for Mac用户实例的对象模型进行交互。

使用Parallels,Mono或Wine运行该应用程序(请参见OSX中的Wine的COM互操作,此问题从未得到解答)不是解决方案,因为该应用程序的规范要求不得以任何方式修改用户计算机。我们只需要假设用户正在运行一个许可的Excel本地副本,然后使用该副本即可……这是我们在Windows上一贯所做的,而且效果很好。

我认为.NET Core是答案,但我找不到在任何地方明确表明我们可以(或将能够)在Mac OSX上使用Excel的本地副本运行.NET Core时从C#访问Excel对象库。适用于Mac。有人可以指出我已经讨论过的地方吗?但是,如果没有,那么请告诉我,如果这在他们的.NET Core路线图中,该如何向Microsoft查找?

c# macos excel com-interop .net-core

2
推荐指数
1
解决办法
939
查看次数

VB6 .Net Interop.将.Net Date属性传递给VB6函数ByRef未更新

我有一个混合的VB6(入口点)到.Net应用程序.

在.Net中,我有一个类,它具有Date属性(Date1-Date4),并且公开了,并且COM Visible等等于VB6代码.

在VB6代码中有一个方法,它采用Date ByRef并修改它.

使用在VB6(dt1-dt4)中声明的日期,这可以正常工作,我传递ByRef的日期变量得到更新,但是如果我在我的类(Date1-Date4)上传递.Net日期,它会更新.

work arround是将TmpDate传递给方法,然后将值分配给.Net属性.

然而,我想找到一个合适的解决方案,因为我正在替换VB6代码,这很容易被遗漏.

VB.Net宣言

<ComVisible(True)>
Public Class DotNetDatesClass
    Implements INotifyPropertyChanged, IDotNetDatesClass

     Private _Date1 As DateTime

     <ComVisible(True)> 
      Public Property Date1 As DateTime Implements IDotNetDatesClass.Date1   
            Get
                Return _Date1
            End Get
            Set(value As DateTime)
                _Date1 = value                   
            End Set
        End Property
Run Code Online (Sandbox Code Playgroud)

VB6示例:

    dotNetDates.Date1 = DEFAULT_DATE
    dotNetDates.Date2 = DEFAULT_DATE
    dotNetDates.Date3 = DEFAULT_DATE
    dotNetDates.Date4 = DEFAULT_DATE

    getDates connectionString, dotNetDates.Date1, dotNetDates.Date2, dotNetDates.Date3, dotNetDates.Date4
Run Code Online (Sandbox Code Playgroud)

解决方法:

    Dim dt1 As Date
    Dim dt2 As Date
    Dim dt3 As Date
    Dim dt4 As Date …
Run Code Online (Sandbox Code Playgroud)

.net vb.net vb6 com-interop vb6-migration

2
推荐指数
1
解决办法
275
查看次数