如何在C#中实现COM接口



不是一个复制品,我已经搜索了好几天的解决方案,进行了很多测试,但没有发现任何真正的帮助。这就是我注册stackoverflow并发布这篇文章的原因。]

[STATION]
我正在尝试在C#中执行COM互操作,但我不太熟悉COM的工作方式
存在一个没有任何.tlb文件的COM库。幸运的是,我在github上的一个开放存储库中找到了它的.idl文件。然后,我将接口声明复制到我自己的项目中,并用C#重写它们
只有当我只检索可以从中调用方法的COM对象时,一切看起来都很好。这个图书馆就是这样运作的。

[问题]
问题是,这个库请求实现一个接口来执行IO操作,该操作应由调用方自定义(例如重定向到stdout/file/printer(
它强制我通过调用dllimport库中的stdcall函数来提供此接口的实例
我尽了我所能,但总是失败
更具体地说,请参阅下面的代码。

[代码]

// The interface I rewrote from .idl file which I must give implementation of.
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid(<GUID>)]
public interface IFoo
{
int Bar(string s);
}
// The implementation I would like to provide
[ClassInterface(ClassInterfaceType.None), Guid<GUID>]
public class MyFoo : IFoo
{
public int Bar(string s)
{
Console.Write(s);
return 0; //S_OK
}
}
// This is the delegate for the function. 
// The function itself is obtained by GetProcAddress
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int Function(IntPtr obj);
// Here's the code I used
Function func = <GetProcAddress stuff>;
IFoo obj = new MyFoo();
IntPtr objPtr = Marshal.GetIUnknownForObject(obj);
int hresult = Function(objPtr);
if (hresult != 0) // S_OK
throw new Exception($"Failed 0x{hresult:x}");

[SO FAR]
如果此函数成功,则hresult应该为0(S_OK(,但它只是不断获得0x80131515
好吧,我确信这个问题与Function无关,因为我发现另一段代码成功了
该代码不是重新定义接口然后实现,而是通过用函数指针填充接口来手动构建接口的VTable
这真的不是我想要的,因为代码看起来不那么干净,也不那么安全
我已经搜索了好几天的解决方案,但只找到了一些关于这方面的信息。COM似乎已经过时了。

问题已解决
有问题的代码本应有效,但没有。我发现这是CLR的COM互操作问题。Function中的某些代码不能简单地以这种方式调用。(通过让GC持有对象(
这是一种非常罕见的情况,很难解释所有细节。有关更多信息,请在dotnet的运行时repo中搜索ReleaseHolder
仅此而已。我只是不知道为什么这个答案说不清楚。无论如何,它再清楚不过了。

相关内容

最新更新