gpt4 book ai didi

c# - 如何制作 PInvoke 友好的 native API?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:36:13 24 4
gpt4 key购买 nike

如何使原生 API 对 PInvoke 友好?

有一些关于如何修改 native 程序以与 P/Invoke 一起使用的提示 here .但是在我编写 native 程序之前,我应该注意哪些事项才能使我的程序/库 PInvoke 友好?

使用 C 或 C++ 都可以。


更新:
如果我编写 C API,我必须做些什么才能使用如下 C# 语法进行 P/Invoke:

[DLLimport("MyDLL.dll")]

是否可以对原生 C++ 代码/库执行相同的操作?


制作 P/Invoke 友好 native API 的一些技巧的总结/改写:
+ 参数应该是本地类型(int、char*、float、...)
+ 参数越少越好
+ 如果动态内存被分配并传递给托管代码,请确保创建一个“更干净”的函数,该函数也被 p/invoked
+ 提供示例和/或单元测试,说明如何从 .NET 调用 API
+ 提供 C++/CLI 包装器

最佳答案

如果您自己控制 native 库,而不是使用 P/Invoke,您可以编写一组包装 native 调用的 C++/CLI 类。在许多情况下,这将比使用平台调用执行得更好,并且您可以获得类型正确性的额外好处。例如,如果您有如下某种 C API(它没有做任何有用的事情,我只是添加了指针和结构来强调它是 native 代码的事实):

struct SomeStruct {
int a, b;
int* somePtr;
};

int foo(struct SomeStruct* a, int b) {
*a->somePtr = a->a + a->b;
return a->b * *a->somePtr + b;
}

您可以创建一个 C++/CLI 类来包装它:

public ref class MyNativeAPI {
private:
SomeStruct* x;
public:
MyNativeAPI() {
x = new SomeStruct;
}
~MyNativeAPI() {
delete x;
}
int Foo(int a) {
pin_ptr<SomeStruct*> ptr = this->x;
return foo(ptr, a);
}
}

然后,您可以在 C# 中调用它:

MyNativeAPI a = new MyNativeAPI();
if(a.Foo(5) > 5) { ... };

您必须阅读有关 C++/CLI 的更多信息,以了解您对托管堆和 native 堆的新控制,以及混合两者的注意事项(如 pin_ptr I上面使用过),但总的来说,它是在 .NET 中实现 native 互操作的更优雅的解决方案。

关于c# - 如何制作 PInvoke 友好的 native API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2091788/

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