文档章节

托管程序调用非托管dll问题总结

Y
 Y13
发布于 2016/05/14 01:40
字数 697
阅读 12
收藏 0
点赞 2
评论 0

托管程序Visual Basic.net, 非托管DLL标准C++程序(使用VC++编译)

函数调用定义

第一种写法:
<DllImportAttribute("XXX.dll", EntryPoint:="xxxxx", CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function Xxxxx(ByVal arg0 As String, ByVal [arg] As Integer, ByVal arg1 As Integer) As IntPtr

第二种写法:

Public Declare Function Xxxxx Lib "XXX.dll" Alias "xxxxx" ((ByVal arg0 As String, ByVal [arg] As Integer, ByVal arg1 As Integer) As IntPtr

问题1:DLLNotFoundException

表示xxx.dll文件没有找到

问题2:EntryPointNotFoundException

表示函数的入口没有找到,EntryPoint:="xxxxx"指定有问题

后面就是高潮了!!!

问题3:PIvokeStackImbalance

相信有一群人死在这里,网上很多人说重启一下网络接口就好了,但是这里我们没有涉及到网络开发(当然我遇到这个问题是开发LOG系统,涉及到了网络开发)

来自bing翻译:

PInvoke 函数调用具有堆栈失去了平衡可能因为 PInvoke 签名托管非托管目标签名匹配请检查 PInvoke 签名参数调用约定匹配目标非托管签名

这个东西绝对会让你云里雾里,当时不妨搜索一下“函数调用约定”也许会找到一下不到的结果

其实是使用VC++默认编译,生成的是__cdecl约定,但是VB上面的写法默认使用的是__stdcall约定,所以才会导致这个错误的发生,这也就是我上面第一种写法后面

会加上CallingConvention:=CallingConvention.Cdecl,来指定其调用约定。所以使用dll的时候,先要确定该dll使用的哪种调用约定。

抵用约定可以使用__declspec(dllexport) || __declspec(dllimport)进行指定(这里指定的是cdecl约定)

问题4:AccessViolationException

这个异常绝对是一个奇葩异常

来自bing翻译

试图读取写入受保护内存通常指示其他内存损坏

想了好久,试了好久,都解决不了,其实这个问题是你的内存已经混乱导致的,就是指定参数类型上出现了大问题。

参数类型指定列表

C/C++

C#

HANDLE, LPDWORD, LPVOID, void*

IntPtr

LPCTSTR, LPCTSTR, LPSTR, char*, const char*,Wchar_t*, LPWSTR

String [in], StringBuilder [in, out]

DWORD, unsigned long, Ulong

UInt32,[MarshalAs(UnmanagedType.U4)]

bool

bool

LP<struct>

[In] ref <struct>

SIZE_T

uint

LPDWORD

out uint

LPTSTR

[Out] StringBuilder

PULARGE_INTEGER

out ulong

WORD

uInt16

Byte, unsigned char

byte

Short

Int16

Long, int

Int32

float

single

double

double

NULL pointer

IntPtr.Zero

Uint

Uint32

我是中枪在void*上面了。

还有写VC++开发的时候最好写微软的类型,这样,微软定义了大量的宏,可以帮你在宽字节和标准字节间转换。

 

以上所说对所有的.net平台受用。

 

最后给几个链接

函数调用约定

DllImportAttribute 类

 

我也写累了。还有问题联系我吧

© 著作权归作者所有

共有 人打赏支持
Y

Y13

粉丝 0
博文 30
码字总数 148304
作品 0
大连
高级程序员
.NET简谈互操作(二:先睹为快)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之释放非托管内存) .NET简谈互操作...

王清培 ⋅ 2011/06/24 ⋅ 0

.NET简谈互操作(五:基础知识之Dynamic平台调用)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之Dispose非托管内存) .NET简谈互操...

王清培 ⋅ 2011/06/29 ⋅ 0

C#调用DLL函数方法

C#调用C++编写的COM DLL 在C#调用C++编写的COM DLL封装库时会出现两个问题: 1. 数据类型转换问题 2. 指针或地址参数传送问题 首先是数据类型转换问题。因为C#是.NET语言,利用的是.NET的基...

AlphaJay ⋅ 2010/08/16 ⋅ 0

C# DllImport用法和路径问题

DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息。 DllImport属性应用于方法,要求最少要提供包含入口点的dll的名称。...

awbeci ⋅ 2013/12/09 ⋅ 0

重新学.Net[二]——从编译到运行

一个托管的程序,从书写代码到编译到最后运行,到底是怎么一个过程,一直有些混沌,好好看了下书,梳理了一下。 托管的程序是二次编译的,因此一个托管程序从第一次编译到最后的运行可以根据...

余二五 ⋅ 2017/11/23 ⋅ 0

[CLI/C++].NET托管代码和非托管代码的相互调用

场景三:现有C++原代码,包装后供C#调用。 C++的原代码,实际上可以直接编译成托管代码。MFC也好ATL也好……这样看起来在.NET中最强大的编程语言就是C++了:它不仅可以编写托管 程序,甚至可...

Yong_Luo ⋅ 2010/10/01 ⋅ 0

让 .Net 程序可以在自定义位置查找托管/非托管 dll 的几种方法

一、自定义托管 dll 程序集的查找位置 目前(.Net4.7)能用的有2种: DEFAULT_IMPLEMENT - 这个算是比较“正统”的方式。程序集通过 AssemblyResolve 事件将程序集文件读入内存后加载,但是磁...

qaqz111 ⋅ 2015/01/03 ⋅ 0

解决:对 PInvoke 函数的调用导致堆栈不对称问题

问题描述: 在使用托管代码调用非托管代码时,发生“对 PInvoke 函数“UseTwiHikVisionDllTest!UseTwiHikVisionDllTest.TwiHikVision::GetFirstPic”的调用导致堆栈不对称。原因可能是托管的...

Yong_Luo ⋅ 2013/04/01 ⋅ 0

动态装载、调用DLL中的非托管函数

(二) 动态装载、调用DLL中的非托管函数 在上面已经说明了如何用DllImport调用DLL中的非托管函数,但是这个是全局的函数,假若DLL中的非托管函数有一个静态变量S,每次调用这个函数的时候,静...

Yong_Luo ⋅ 2010/09/28 ⋅ 0

C#在.NET编译执行过程

1..NET语言的编译器接受源代码文件,并生成名为程序集的输出文件。 程序集要么是可执行的,要么是DLL 程序集里的代码并不是本机代码,而是一种名称为CIL的中间语言 程序集包含如下信息: 程序...

幕三少 ⋅ 2014/03/22 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

spring Email

一、普通邮件 maven依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.2.6.RELEASE</version>......

BobwithB ⋅ 8分钟前 ⋅ 0

spark 整理的一些知识

Spark 知识点 请描述spark RDD原理与特征? RDD全称是resilient distributed dataset(具有弹性的分布式数据集)。一个RDD仅仅是一个分布式的元素集合。在Spark中,所有工作都表示为创建新的...

tuoleisi77 ⋅ 11分钟前 ⋅ 0

思考

时间一天天过感觉自己有在成长吗?最怕的是时光匆匆而过,自己没有收获!下面总结下最近自己的思考。 认识自己 认识另一个自己,人们常说要虚心听取别人意见和建议。然而人往往是很难做到的,...

hello_hp ⋅ 12分钟前 ⋅ 0

IT行业的变革就像世界杯德国对战墨西哥一样难以预测[图]

最近在观看世界杯,尤其是昨天的比赛,上一届卫冕冠军德国队居然0:1告负墨西哥,这创造了历史,首先是墨西哥从来没赢过德国队,其次是德国队36年来首站没输过,再差也是打平,而这次,德国队...

原创小博客 ⋅ 31分钟前 ⋅ 0

解决CentOS6、7,/etc/sysconfig/下没有iptables的问题

一、Centos 6版本解决办法: 1.任意运行一条iptables防火墙规则配置命令: iptables -P OUTPUT ACCEPT 2.对iptables服务进行保存: service iptables save 3.重启iptables服务: service ...

寰宇01 ⋅ 41分钟前 ⋅ 2

数据库备份和恢复

备份:mysqldump -u root -p 数据库>磁盘路径 恢复:mysql -u root -p 数据库<sql脚本的磁盘路径

anlve ⋅ 今天 ⋅ 0

发生了什么?Linus 又发怒了?

在一个 Linux 内核 4.18-rc1 的 Pull Request 中,开发者 Andy Shevchenko 表示其在对设备属性框架进行更新时,移除了 union 别名,这引发了 Linus 的暴怒。 这一次 Linus Torvalds 发怒的原...

问题终结者 ⋅ 今天 ⋅ 0

在树莓派上搭建一个maven仓库

在树莓派上搭建一个maven仓库 20180618 lambo init 项目说明 家里有台树莓派性能太慢。想搭建一个maven私服, 使用nexus或者 jfrog-artifactory 运行的够呛。怎么办呢,手写一个吧.所在这个...

林小宝 ⋅ 今天 ⋅ 0

Spring发展历程总结

转自与 https://www.cnblogs.com/RunForLove/p/4641672.html 目前很多公司的架构,从Struts2迁移到了SpringMVC。你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢?...

onedotdot ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部