C#调用C++函数入口点的问题 z
C++使用 void extern __declspec(dllexport) 函数名()定义的输出函数, 在C#中调用时, 如前文所述, 使用
[DllImport("D:\VS2005Projects\Dev_PetroSim2010b\Dev_AMDBR\Debug\Dev_DR_AMDBR.dll", EntryPoint = "#1")]
public static extern void amDBRSurfaceTensionEX(int compCount, int[]
components, int modelID, [MarshalAs(UnmanagedType.LPArray,
SizeParamIndex = 1)] double[] Z, ref int errorID);
来调用.
这里注意的是,定义函数入口点的参数EntryPoint = "#1", C#中有2种方式可以定义入口点,
一种是以序号加前缀"#",这是我一直用的,另一种是用EntryPoint="函数名",这种方法我试了很多次却无法实现,C#编译器总会说在DLL中
没有找到函数.
如何找到函数所对应的EntryPoint编号呢?我用的是一个叫DLLExportViewer的软件,可以告诉你各个函数的Ordinal,即
编号,照此调用即可,但是问题是,如果原DLL进行编辑之后,增加或减少输出函数之后,各个函数的编号会重新打乱,使原程序无法进行.所以对这种情况,即
DLL尚在编辑之中时,还是以函数名作为EntryPoint比较好.
在C:Program FilesMicrosoft Visual Studio 8VCbin目录中,有一个文件dumpbin.exe文件和DLLExportViewer一样可以查看DLL的输出函数,但是在运行时,居然跳出一个错误窗口
查找后发现,mspdb80.dll文件是在C:Program FilesCommon FilesMicrosoft
SharedVSA8.0VsaEnv中,将此文件复制到C:Program FilesMicrosoft Visual Studio
8VCbin目录,再运行时错误消失.
查阅dumpbin的输出,发现输出函数说明及如下
| ordinal | hint | RVA | name |
| 7 | 6 | 0002D591 | ?amDBRSurfaceTensionEX@@YAXHPAHHPANAAH@Z = @ILT+1420(?amDBRSurfaceTensionEX@@YAXHPAHHPANAAH@Z) |
前面的ordinal 7即为函数的输出序号, name列即为可用的函数名,在C#中,改函数声明为如下即可用函数名作为EntryPoint
[DllImport("D:VS2005ProjectsDev_PetroSim2010bDev_AMDBRDebugDev_DR_AMDBR.dll",
EntryPoint = "?amDBRSurfaceTensionEX@@YAXHPAHHPANAAH@Z")]
============================================
照上述做法,导出函数可以成功,但是在C#中调用却是相当麻烦,因为函数的入口名称太过繁杂且不可理解,因此,还是要解决在C++中的函数输出,以使在C#中能直接以函数名作为入口.
上述问题中,实际上是在C++中函数输出时,默认输出名是使用C++的mangled name, 要使用C的命名方式方可直接使用其输出名,这时,函数输出声明应改为如下:
extern "C" __declspec(dllexport) void amDBREnthalpyEX(int CompCount,
int* streamComp, int modelID, double* streamInfo, int& errorID)
这样,可以看到DLLExportViewer的查看结果了,以此方式声明的amDBREnthalpyEX函数和以原方式声明的其他函数的名称的不同如下图所示.
这时,在C#中,就可以以函数名称作为入口点了:
[DllImport("D:VS2005ProjectsDev_PetroSim2010bDev_AMDBRDebugDev_DR_AMDBR.dll", EntryPoint = "amDBREnthalpyEX")]
public static extern void amDBREnthalpyEX(int compCount, int[]
components, int modelID, [MarshalAs(UnmanagedType.LPArray,
SizeParamIndex = 1)] double[] Z, ref int errorID);
C#调用C++函数入口点的问题 z的更多相关文章
- 可执行程序的入口点在那里?(强化概念:程序真正的入口是mainCRTstartup)
今天终于有时间来研究一下一个很大很大的工程编译成一个exe和若干dll后,程序是如果执行它的第一条指令的?操作系统以什么规则来找到应该执行的第一条指令(或说如何找到第一个入口函数的)? 我们以前写wi ...
- vs/windows程序找不到入口点cuvidGetDecodeStatus于AppDecGL.exe动态链接库上
解决方法:这个问题的原因是由于使用的英伟达显卡驱动版本不够新,更新显卡驱动即可. 找了一个多月的原因,终于知道起源了.最终问题还是出在了nvcuvid.lib/.dll上面.通过分析vs调试信息可以得 ...
- C# 互操作性入门系列(二):使用平台调用调用Win32 函数
好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...
- [转]C# 互操作性入门系列(二):使用平台调用调用Win32 函数
传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...
- 如何为WPF添加Main()函数 程序入口点的修改
一般的.WPF的Main()函数是自动生成的,不过有时候我们需要为我们的应用程序传参.那么自动生成的Main()函数就不会满足我们的要求. 那么如何为WPF Application 设置Main()函 ...
- 在纯C工程的main函数之前跑代码(手工找到程序入口点, 替换为我们自己的函数)
在main函数之前跑代码的方法 方法: 手工找到程序入口点, 替换为我们自己的函数 写测试程序 // test.cpp : Defines the entry point for the consol ...
- (转) MFC的入口点与消息循环,消息映射
博文分析的很不错,尤其是替换默认窗口过程的这块,本人觉得,所有的这些都可以参阅侯杰的<深入浅出MFC >. 来自:http://blog.csdn.net/sryan/article/de ...
- Android程序的入口点
原文:Android程序的入口点 android应用程序,由一到多个Activity组成.每个Activity没有很紧密的联系,因为我们可以在自己的程序中调用其它Activity,特别是调用自己的代码 ...
- 逆向课程第二讲,寻找main入口点
逆向课程第二讲,寻找main入口点 一丶识别各个程序的入口点 入门知识,识别各个应用程序的入口点 (举例识别VC 编译器生成,以及VS编译生成的Debug版本以及Release版本) 1.识别VC6. ...
随机推荐
- MySql的安装与使用
今天因为毕业设计要用到MySql数据库,所以就准备自己安装一个MySQL数据库,但是因为MySQL Install MSI只有32位,所以最后选择使用Windows (x86, 64-bit), ZI ...
- Kali-Linux之开启ssh服务
需求:通过putty软件ssh到Kali-Linux系统 问题:默认情况下,Kali系统的ssh服务并没有开启 操作方法: 1.编辑sshd_config文件 root@kali:~# vi /etc ...
- jQuery关于导航条背景切换
效果如下: <DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jqu ...
- BFC(Box,Formatting,Context) —— 块级格式化上下文
Box:CSS布局的基本单位 Formatting context是页面中的一块渲染区域,最常见的是BFC和IFC,CSS3增加了GFC和FFC BFC定义:块级格式化上下文,它是一个独立的渲染区域, ...
- 使用python抓取有路网图书信息(原创)
以前挺喜欢去有路网买二手书的,但是有路网有个缺陷,就是放在图书列表中的书很多都没货了,尤其是一些热门的方向,比如android,在列表中的书大多都没有货了,你必须一个一个点进入查看详细信息才能得知图书 ...
- thinkphp验证码的实现
两种验证码验证实现,一种直接在form表单提交按钮实现验证,一种使用ajax传递参数实现验证: 1.直接在form表单提交按钮实现验证,在控制器VerifyController.class.php中写 ...
- phpcms v9后台多表查询分页代码
phpcms v9里面自带的listinfo分页函数蛮好用的,可惜啊.不支持多表查询并分页. 看了一下前台模板层支持get标签,支持多表查询,支持分页.刚好可以把这个功能搬到后台来使用. 我们现在对g ...
- linux磁盘设备知识
linux分区数字编号: 1.分区数字编号1至4留给主分区或扩展分区使用,逻辑分区编号从5开始. 2.IDE硬盘设备名均以/dev/hd开头,不同硬盘编号依次是/dev/hda/./dev/hdb./ ...
- Javascript的websocket的使用方法
javascript websocket接口 web实现客户端和服务端双向发送消息的方法有: 轮询,客户端定期向服务端请求: 长轮询,客户端定期向服务端请求,服务端只有有信息发送的时候才返回respo ...
- [C和指针] rearrange.c
C和指针_程序1.1_重排字符 /* ** 这个程序从标准输入(键盘)中读取输入行并按需求处理后在标准输出(屏幕)中打印, ** 每个输入行的后面一行是该行按需求处理后的输出内容. ** ** 输入的 ...