文档章节

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

Y
 Y13
发布于 2016/05/14 01:40
字数 697
阅读 15
收藏 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简谈互操作(五:基础知识之Dynamic平台调用)

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

王清培
2011/06/29
0
0
.NET简谈互操作(二:先睹为快)

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

王清培
2011/06/24
0
0
C# DllImport用法和路径问题

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

awbeci
2013/12/09
0
0
动态装载、调用DLL中的非托管函数

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

Yong_Luo
2010/09/28
0
0
重新学.Net[二]——从编译到运行

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

余二五
2017/11/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

TypeScript基础入门之JSX(二)

转发 TypeScript基础入门之JSX(二) 属性类型检查 键入检查属性的第一步是确定元素属性类型。 内在元素和基于价值的元素之间略有不同。 对于内部元素,它是JSX.IntrinsicElements上的属性类型...

durban
20分钟前
0
0
AVA中CAS-ABA的问题解决方案AtomicStampedReference

了解CAS(Compare-And-Swap) CAS即对比交换,它在保证数据原子性的前提下尽可能的减少了锁的使用,很多编程语言或者系统实现上都大量的使用了CAS。 JAVA中CAS的实现 JAVA中的cas主要使用的是...

码代码的小司机
23分钟前
0
0
Android JNI开发系列(十三) JNI异常处理

JNI 异常处理 JNI异常与JAVA处理异常的区别 JAVA 有异常处理机制,而JNI没有 如果JAVA中异常没有捕获,后面的代码不会执行,JNI会执行 JAVA编译时的异常,是在方法显示的声明了某一个异常,编...

蔡小鹏
36分钟前
2
0
简单介绍Java 的JAR包、EAR包、WAR包区别

WAR包 WAR(Web Archive file)网络应用程序文件,是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。War专用于Web方面。大部分的JAVA WEB工程,都是打成WAR包进行发布的。 War是...

Linux就该这么学
今天
1
0
Qt那些事0.0.7

在帮助文档(Overview - QML and C++ Integration)中随缘遇到一张图,是关于C++对象与QML整合介绍的,值得标记下来,虽然大部分功能也有所涉猎,但是还是留个记号,万一哪天我失忆了还想写Q...

Ev4n
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部