【发布时间】:2016-05-06 11:02:05
【问题描述】:
我想从 C++ 调用一个 C# 库。
C# 库,请求一个委托函数, 为了报告结果。
也许我的目的令人困惑:概念是,C++ 调用 C# 函数,而 C# 函数将从 C++ 调用回调函数。
我在 C# 调用 C++ 回调函数中被阻止了,COM Interop 对我来说是神秘的。
我的示例代码是:
C#代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace CSharpLibraryNameSpace
{
// Interface declaration.
public delegate int NativeDelegateType(int x);
//public delegate int NativeDelegateType([In, MarshalAs(UnmanagedType.LPStr)] string arg1);
public interface ManagedInterface
{
int Add(int Number1, int Number2);
int CalltheCallbackFun(NativeDelegateType callbackFun);
};
// Interface implementation.
public class ManagedCSharpClass : ManagedInterface
{
public int Add(int Number1, int Number2)
{
Console.Write("Add\n");
return Number1 + Number2;
}
public int
CalltheCallbackFun(
/*[MarshalAs(UnmanagedType.FunctionPtr)]*/ NativeDelegateType callbackFun)
{
Console.Write("BB\n");
string str;
str = "AAA";
unsafe
{
fixed (char* p = str)
{
Console.Write("before call callbackFun\n");
callbackFun(0x01);
}
}
return 0;
}
}
}
C++ 代码:
#include <windows.h>
// Import the type library.
#import "CSharpLibrary.tlb" raw_interfaces_only
using namespace CSharpLibrary;
typedef void (__stdcall * C_Callback)(int);
__declspec(dllexport) int __stdcall theCallback(void)
{
return 0;
}/*theCallback*/
class CPPcallback :public _NativeDelegateType
{
public:
CPPcallback(){};
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
/* [out] */ UINT *pctinfo)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo **ppTInfo)
{
if (ppTInfo == NULL)
return E_INVALIDARG;
*ppTInfo = NULL;
if(iTInfo != 0)
return DISP_E_BADINDEX;
AddRef(); // AddRef and return pointer to cached
// typeinfo for this object.
*ppTInfo = NULL;
return NOERROR;
}
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR *rgszNames,
/* [in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID *rgDispId)
{
return E_NOTIMPL;
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS *pDispParams,
/* [out] */ VARIANT *pVarResult,
/* [out] */ EXCEPINFO *pExcepInfo,
/* [out] */ UINT *puArgErr)
{
return 0;
}
virtual HRESULT STDMETHODCALLTYPE QueryInterface(/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{
if (riid == IID_IUnknown)
{
*ppvObject = static_cast<IUnknown*>(this);
AddRef();
return S_OK;
}
if (riid == IID_IDispatch) {
*ppvObject = static_cast<IDispatch*>(this);
AddRef();
return S_OK;
}
//if (riid == IID_CPPcallback )
{
*ppvObject = static_cast<CPPcallback*>(this);
AddRef();
return S_OK;
}
*ppvObject = NULL;
return E_NOINTERFACE;
}
virtual ULONG STDMETHODCALLTYPE AddRef( void)
{
return InterlockedIncrement(&_refCount);
}
virtual ULONG STDMETHODCALLTYPE Release( void)
{
return InterlockedDecrement(&_refCount);
}
private:
long _refCount;
};
int main(int argc, char *argv[])
{
// Initialize COM.
HRESULT hr = CoInitialize(NULL);
// Create the interface pointer.
ManagedInterfacePtr CSharpDLLPtr(__uuidof(ManagedCSharpClass));
long lResult = 0;
// Call the Add method.
CSharpDLLPtr->Add(5, 10, &lResult);
long aa;
aa = 3;
CPPcallback cppcallback;
CSharpDLLPtr->CalltheCallbackFun(&cppcallback, &aa);
wprintf(L"The result is %d\n", lResult);
// Uninitialize COM.
CoUninitialize();
return 0;
}
C++ 调用 C# 函数有效。但是线 CSharpDLLPtr->CalltheCallbackFun(&cppcallback, &aa);
会进入函数QueryInterface,GetTypeInfo然后直接回到C++主函数。那是 C# 中的那一行
Console.Write("before call callbackFun\n");
无法到达。
如何在 C# 中注册 C++ 回调函数?
【问题讨论】:
标签: c# c++ com-interop