C++からC#ライブラリを呼びたいと思います。C++がC#関数を呼び出すときに、C#から委譲されたC++関数を呼び出す方法は?
C#ライブラリは、結果を報告するために委任された関数 を要求します。
多分私の目的は混乱しています:概念は、C++のC#関数を呼び出し、C#関数はC++からコールバック関数を呼び出します。
私はC#コールのC++コールバック関数でブロックされていますが、COM相互運用機能は私にとっては不可解です。
私のサンプルコードは、可能:
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++コード: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。しかし、行 CSharpDLLPtr-> CalltheCallbackFun(& cppcallback、& aa);
は、QueryInterface、GetTypeInfo関数に入り、次にC++ main関数に直接戻ります。 C#の行です。
Console.Write("before call callbackFun\n");
に到達しませんでした。
C#でC++コールバック関数を登録するにはどうすればよいですか?
ありがとう、私はここにコメントする必要があります タイプ交換することがより良いです:私は 'var'タイプの交換について理解していなかった@GaigerChen VAR より良い互換性 –
ため NativeDelegateType などを?トピックについては、 'PInvoke'を使用して追加することには多くの利点があります。ラッパーを記述する必要はなく、' C++配列 '、' LPCTSTR'と 'Structs'を明示的に変換することなく渡すことができます。 –
私の環境では:VS2005、varの使用はコンパイラによって渡されませんでしたが、NativeDelegateTypeは可能でした。 –