[NOT A DUPLICATE, I've searched for solutions for days and had performed a lot of tests only to find nothing really helps. That's why I registered stackoverflow and posted this.]
[SITUATION]
I am trying to perform COM interops in C# but I'm not quite familiar with how COM works.
There's a COM library without any .tlb file. Fortunately I found its .idl file in an open repository on github. Then I copied the interface declarations to my own project and rewrote them in C#.
Everything looks great only if I just retrieve COM objects from which methods can be called. That's how this library works.
[PROBLEM]
Well the problem is, this library requests for an implementation of an interface to perform IO operations which shall be customized(e.g. redirection to stdout/file/printer) by the caller.
It forces me to give an instance of this interface by calling an stdcall
function from a dllimport
library.
I tried everything I can, just keeps failing.
To be more specific, see the code below.
[CODE]
// 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]
The hresult
is supposed to be 0(S_OK) if this function succeeds, but it just keeps getting 0x80131515
.
Well, I'm convinced that the problem has nothing to do with the Function
, because I found another snippet of code succeeded.
Instead of redeclaring the interface then implement, that code just manually constructs a VTable for the interface by filling it with function pointers.
That's really not what I want, because the code looks not so clean, neither so safe.
I've been searching for solutions for days, but just found little information about this. Seems COM has been out of date.