gpt4 book ai didi

c# - 从 C++ 库调用 C++/CLI 函数

转载 作者:行者123 更新时间:2023-11-30 21:22:51 24 4
gpt4 key购买 nike

我需要将原生 C++ 库集成到 C# 项目中。现在在这个 C++ 库中有一个类,我需要在 C++/CLI 中继承它的虚函数。所以在 C++/CLI 中我写了一些类似的东西

class C++CliClass : public C++Class
{
C++CliClass(Callback callback) { iCallback = callback; }
virtual VirualFunctionCallFromC++(int x, int y, int z, SomeClass *p)
{
// I need to call C++/CLI here
iCallback(x, y, z, p);
}

private:
Callback iCallback;
}

I defined the callback function as:
typedef int (__cdecl *Callback)(int x, int y, int z, SomeClass *p);

The idea is now that C++ library calls the virtual function of the C++Cli
class which on his turn calls the call back which gets me hopefully into C#.

// This delegate definition is needed to setup the callback for the C++ class
delegate int CallbackDelegate(int x, int y, int z, SomeClass *p);

So now I defined a managed C++/CLI class
public ref class GCClass
{
public:
delegate <Byte>^ GetDataDelegate();
GCClass(GetData^ getDataDelegate) { iGetDataDelegate = getDataDelegate };

private:
GetDataDelegate ^iGetDataDelegate;
int GetData(int x, int y, int z, SomeClass *p)
{
// call delegate into C#
<Byte>^ data = iGetDataDelegate->Invoke();
}
public:
void SomeFunctionWhichEventuallyCallsC++Libary
{
// create a delegate for the method that will call the C# delegate
CallbackDelegate ^d = gcnew CallbackDelegate(this, &GCClass::GetData);
IntPtr del = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(d);

// Install in the C++ class
C++CliClass(del.ToPointer());

// Setup the C++ library and install my C++ class into the library
SomeObjectOfTheLibrary->Install(&C++CliClass);
SomeObjectOfTheLibrary->DoSometing() // will call the C++ virtual function and end up in C#

// The delegate is no longer needed anymore
}

代码到此为止。所以我希望实现的是有人可以调用我的托管 C++/CLI 类的方法,该类使用 native C++ 库来完成他的工作。 C++ 库依次调用 C++/CLI 回调,最后调用 C# 委托(delegate)。现在终于有了问题:在 Debug模式下一切正常。然而,在 Release模式下,有时会抛出 AccesException 或有时应用程序会挂起。我怀疑这与 C++/CLI 和 C++ 的不同调用约定有关。例如,我观察到第二次调用回调时 iCallback 的值与第一次调用时不同。然而,对于所有下一次调用,iCallback 的值不再改变。我希望 iCallback 值应该始终相同,但我不确定,因为我不知道框架内部如何工作才能从 C++ 调用委托(delegate)。我还尝试使用 [UnmanagedFunctionPointer(Cdecl)] 定义 CallbackDelegate 的调用约定。我尝试了所有选项但没有结果:我总是以异常结束或应用程序永远挂起。有人可以提示我可能出了什么问题吗?

最佳答案

确保委托(delegate)在仍然需要时未被垃圾回收。在 C++CliClass 类中,您可以添加一个 CallbackDelegate 类型的成员并将其设置为 d。如果 C++CliClass 的实例仅在执行 SomeFunction 期间存在。. 函数末尾的 GC.KeepAlive(d) 可能就足够了。

也许更简单:在 C++CliClass 中定义一个 gcroot 类型的成员,然后在 VirtualFunction 中直接调用这个成员的 GetData 函数,而不需要委托(delegate)。

关于c# - 从 C++ 库调用 C++/CLI 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2108552/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com