Ich möchte eine C# -Bibliothek aus C++ aufrufen.Wie Sie eine C++ - delegierte Funktion aus C# aufrufen, wenn C++ - Aufruf C# funktioniert?
Die C# -Bibliothek, fordern Sie eine delegierte Funktion, , um die Ergebnisse zu melden.
Vielleicht ist mein Zweck verwirrend: die Konzeption ist, C++ Call C# -Funktion, und die C# -Funktion würde eine Callback-Funktion aus C++ aufrufen.
Ich wurde in der C# Call C++ - Callback-Funktion blockiert, die COM-Interop ist für mich geheimnisvoll.
Mein Beispiel-Code sein:
C# -Code:
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;
}
}
}
Der C++ Code:
#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;
}
Die C++ ruft C# Funktion funktioniert. Aber die Linie CSharpDLLPtr-> CalltheCallbackFun (& cppcallback, & aa);
würde in die Funktion QueryInterface, GetTypeInfo dann zurück zu C++ Hauptfunktion direkt gehen. Das ist die Zeile in C#
Console.Write("before call callbackFun\n");
würde nicht erreicht werden.
Wie soll ich eine C++ - Callback-Funktion in C# registrieren?
Vielen Dank, aber ich sollte hier Kommentar: es gut ist, die Art zu ersetzen: var als NativeDelegateType für eine bessere Kompatibilität –
@GaigerChen ich über das Ersetzen 'var' Typ nicht verstanden ? Betreffend Thema möchte ich hinzufügen, dass 'PInvoke' hat eine Menge Vorteile: Sie müssen nicht Wrapper schreiben, können Sie' C++ Arrays', 'LPCTSTR' und' Structs' übergeben ohne explizite Konvertierung, es schneller etc .. –
An meiner Umgebung: VS2005, Verwendung von Var konnte nicht vom Compiler übergeben werden, aber NativeDelegateType konnte. –