首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VB5 dll,如何从C# ( .NET 4.5 )调用函数

VB5 dll,如何从C# ( .NET 4.5 )调用函数
EN

Stack Overflow用户
提问于 2016-04-14 11:35:44
回答 2查看 308关注 0票数 8

我的问题是简单的

VB.dll (我猜是VB5.0)包括这些方法

代码语言:javascript
复制
Private Declare Function ffr_device_find Lib ".\ffr_32.dll" () As Boolean
Private Declare Function ffr_data_transceive_ex Lib ".\ffr_32.dll" (ByVal sp_sdata As String, ByVal sp_rdata As String) As Boolean

in C#..。( .NET 4.5 )

代码语言:javascript
复制
[DllImport("FFR_32.dll", CallingConvention = CallingConvention.Cdecl)]
extern public static Boolean ffr_device_find();

[DllImport("FFR_32.dll", CallingConvention = CallingConvention.Cdecl)]
extern public static void ffr_data_transceive_ex([Out] string sp_sdata, [Out] string sp_rdata);
// FYI, I tried [Out], out, and ref but to no avail.

第一个工作很棒的

但第二个错误导致了这个错误。

对PInvoke函数'ffr_data_transceive_ex‘的调用使堆栈不平衡。 这可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。

FYI

这是VB的工作代码..。(不是内部DLL源)

代码语言:javascript
复制
Dim st As String
Dim rData As String * 40

st = "4401" & "20202020202020202020202020202020"
Text1.Text = st
Cal_BCC
Call ffr_data_transceive_ex(Text1.Text, rData)
Text2.Text = rData

我甚至不明白Dim rData As String * 40是怎么回事.当0rData时,它会变成0吗?当rData1的时候变成1

我的DllImport方法在C#中有什么问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-14 12:12:01

代码语言:javascript
复制
   [DllImport("FFR_32.dll", CallingConvention = CallingConvention.Cdecl)]

不是Cdecl。Visual假定默认为StdCall。在第一个函数中,您可以不使用它,因为它不带任何参数。由于堆栈不平衡,调用方和被调用方都会从堆栈中弹出参数,迫使MDA介入并告诉您严重的问题。

只需完全删除该属性,就可以在C#程序中获得正确的默认设置,CallingConvention.StdCall。

代码语言:javascript
复制
   void ffr_data_transceive_ex([Out] string sp_sdata, [Out] string sp_rdata)

您不能使用string,字符串在.NET中是不可变的。请使用StringBuilder。一定要确保它的容量足够大,能够存储函数写入的接收数据。猜测过低会导致堆损坏,这是一个非常讨厌的错误,很难排除。

还有可能是byte[],您的问题没有很好地记录返回数据的类型。VB5还没有字节类型,所以固定字符串(比如string * 40)是下一个最佳选择。也不能在.NET中工作,并不是所有可能的字节值都有相应的Unicode代码点。只有当您知道函数只返回StringBuilder代码时,才使用ASCII。

票数 7
EN

Stack Overflow用户

发布于 2016-04-15 00:07:54

我选择汉斯?帕桑特?的答案。

但是对于那些想要这个案例的精确解决方案的人,我会给你们一些额外的信息和一些代码片段。

First

就像汉斯·帕桑所说的,CallingConvention应该被抛弃。

第二

正如Hans所说,字符串不应该传递到函数中。更准确地说,第一个参数可以作为string类型传递。但是第二个应该是显式长度的char[]

我对此进行了测试,当长度不同时,它会引发另一个错误。

工作代码

代码语言:javascript
复制
extern public static void ffr_data_transceive_ex([Out] string sp_sdata, [Out] char[] sp_rdata);

必需成分

代码语言:javascript
复制
// To pass the second parameter.
// Because the dll returns 40 length characters, this should be specified as length '40'
char[] ForCardHex = new char[40];

// Command is an already defined protocol format, like "200080581028000001"
// , which can be taken as string.
ffr_data_transceive_ex(Command, ForCardHex);

这非常有效,它在ForCardHex上返回预期值。您应该使用char[]。我无法将byte[]传递到函数中。

感谢所有的评论员和回答者。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36621884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档