C#怎么调用C++的dll?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#怎么调用C++的dll?相关的知识,希望对你有一定的参考价值。

C++头文件原形:
/*
**函数:libIoCtrlInit
**函数说明:初始化驱动及导入SDK动态库
**参数:hlib 模块地址指针,bios_id 主板BIOS ID号,在主板BIOS setup中可以查看得
到、
**返回值: 0 成功,非0失败 ,成功时并导出HMODULE的实例
*/
extern "C" __declspec(dllexport) int libIoCtrlInit(HMODULE *hlib,char* bios_id);

/*
**函数:setPinLevel
**函数说明:设置管脚的输入输出状态
**参数:hlib 模块地址指针,index 管脚序号(参看GPIO_INDEX枚举定义),curstate 设
置管脚输入输出状态,0为低电平,1为高电平(仅为寄存器状态,实际电路的状态,取决于外
部电路)
**返回值: 0 成功,非0失败
*/
extern "C" __declspec(dllexport) int setPinLevel(HMODULE *hlib, GPIO_INDEX index,
GPIO_LEVEL curstate);

C#声明:

[DllImport("libIoCtrlx86.dll",CallingConvention = CallingConvention.Cdecl)]
public static extern int libIoCtrlInit( IntPtr hlib, string bios_id);

[DllImport("libIoCtrlx86.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int setPinLevel( IntPtr hlib, GPIO_INDEX index,GPIO_LEVEL curstate);

C#调用方法:
int a = 1; int b= 1;
string bios_id = "M56L6R"
IntPtr hlib= Marshal.AllocHGlobal(2000);
a=libIoCtrlInit( hlib, bios_id);
b=setPinLevel( hlib, GPIO_INDEX.GPIO_PIN1, GPIO_LEVEL.GPIO_HIGH_LEVEL);

大写字母的是枚举类型,不会出错,这样运行后,a=0,b=-1,根据SDK资料等于0是成功的,是哪里出错了?造成初始化是成功的,然而后面的操作都是失败的?并不知道模块有多大,但DLL文件只有10多K,申请内存的地址大小都改过,没有作用,ref 也用过,也是没有作用, 哪位大佬帮忙看看?我实属菜鸟,谢谢! 电路跟系统没有问题,随SDK有个小程序,用那个程序可以读写IO是正常的.

参考技术A 首先,C#是可以调用C写的DLL的,引用时VS会自动将这个DLL转换为托管程序。 但是你这个DLL是去调用别的C库就会出问题,因为别的库依然是非托管的。追问

这个dll应该没有去调用别的C库的,我贴出来的总共两条语句,第一条应该是成功的,返回值是0,然后利用第一条初始化返回的是0,应该是成功了,后面的一条一句要利用第一条语句返回的句柄去写IO,然后就失败了,我不知道我这样引用句柄是对的还是错了

本回答被提问者采纳

创建 C++ Dll,并从 C# 调用它

【中文标题】创建 C++ Dll,并从 C# 调用它【英文标题】:Creating C++ Dll, and call it from C# 【发布时间】:2009-12-23 05:43:58 【问题描述】:

在我的项目中,我得到了一个带有 C++ 示例代码的设备。代码没问题,设备按预期工作。

但我需要它来与我的 C# 接口通信,因为所有其他设备当前都在使用 C# 接口。

所以我打算为驱动程序创建一个 DLL Wrapper。我将创建自己的 C++ 库(从具有适当接口的源代码)并使用 DLLImport 从 C# 调用此 C++ 库(只需在那里调用我的接口。)。

我很确定可以通过这种方式完成,但我从未创建过 C++ 库并从 C# 中使用过它。那么,任何人都可以向我推荐一些与我的问题相关的教程吗?

我正在使用 C++/C# int VS.NET 2008。

问候, 马克苏德

【问题讨论】:

【参考方案1】:

看看using a class defined in a c++ dll in c# code

【讨论】:

【参考方案2】:

您可以使用的另一个有用工具是C++ CLI。

您可以使用 C++ CLI 创建一个中间库 - 一个公开托管类但运行非托管 C++ 代码的库。您实际上可以在同一个 DLL 中混合托管和非托管 C++。

非托管部分无需使用 PInvoke 函数即可访问非托管 DLL。

您的 C# 代码可以访问此中间库中的托管类。

【讨论】:

+1。您实际上可以在同一个 DLL 中混合托管和非托管 C++。 @RickNZ - 这就是我试图传达的内容,但肯定不够清楚。我现在已将您的句子合并到消息中,谢谢。 除非你打算将你的库移植到 Mono,它不支持 C++/CLR 中的本机代码,否则这绝对是正确的选择。 游戏名称是C++/CLI,不是CLR。 (en.wikipedia.org/wiki/C%2B%2B/CLI) 我以 Jonathan Swift 的博客 (blogs.msdn.com/jonathanswift/archive/2006/10/02/780637.aspx) 为起点。现在看看 CLR 是否解决了我的问题。【参考方案3】:

根据 DLL 和您需要执行的操作,您可能不需要直接创建包装器。您也许可以使用 P/Invoke 来获得这些功能。您将需要评估您的特定需求以及提供的库/代码中已有的内容。

【讨论】:

【参考方案4】:

对于遇到这个问题并正在寻找答案的任何人,您可能想尝试一下刚刚向公众发布的xInterop NGen++ , a C# wrapper generator for native C++ DLL,该工具可以使用高级自动立即生成原生C++ DLL的C#包装器P/Invoke 技术。查看当前版本,免费版本即将推出。

(我是工具的作者)

【讨论】:

第 2 版似乎仍处于早期的 pre-alpha 阶段。界面繁琐,不生成文件。 (“发生异常:无法检索 PDB 信息..”) @StuWeldon,您可能尝试为当前试用版尚不支持的 C 样式 DLL 构建 C# 包装器,我们已在无法下载的最新版本中添加了 C 样式 DLL 支持然而。因此,如果您仍然对使用 xInterop NGen++ 为您的 C 样式 DLL 创建包装器感兴趣,请使用我们网站上的联系我们页面与我们联系,我们应该能够解决您遇到的问题。其他人有任何问题,也请通过xinterop.com与我们联系,我们将更好地为您提供支持。

以上是关于C#怎么调用C++的dll?的主要内容,如果未能解决你的问题,请参考以下文章

C# 调用C++ DLL,而c++函数的有一个参数需要是null,该怎么传递?

C#调用C++ dll 回调

C#调用C++的dll库怎么传递结构体中不定长度的char数组

用C++封装了Halcon的算法,返回值为Hobject类型,在C#中调用dll怎么用Hobject类型的返回值。

C#调用C++的dll,dll中需要传入一个 uchar *的一个 500M内存空间的首地址,现在

c#调用c++写的dll,用dllimport后说啥 找不到指定模块。这个问题你是怎么解决的