【发布时间】:2016-04-14 11:35:44
【问题描述】:
我的问题很简单
VB.dll(VB5.0 我猜)包括这些方法
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
在 C# 中......(.NET 4.5)
[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 签名的参数与目标非托管签名匹配。
仅供参考
这是来自 VB 的工作代码...(NOT INNER DLL SOURCES)
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 是什么意思...当rData 是0 时它会变成0 吗?当rData 有1 时变成40? ...
我在 C# 中的 DllImport 方法有什么问题???
【问题讨论】:
-
你确定
ccr_data_transceive_ex的第一个参数是[Out]吗?因为在您提供的示例中,我没有看到它用作输出参数。 -
* 40在 VB 中使字符串具有 40 的固定预分配长度。在 C# 中尝试:[Out] StringBuilder sp_rdata其中 sp_rdata 是new StringBuilder(40),如果是事实,则对sp_sdata执行相同操作输出,否则删除输出。ccr_data_transceive_ex不是void它的boolean。 -
@Peping 它应该使用
[Out], ref or out,因为 dll 将参数作为ByVal -
@AlexK。是的,好点。但我以前试过……
void和boolean ( or bool )也不起作用。它产生同样的错误。 -
@Peping
ByVal在 VB 中应用于字符串时具有不同的含义。将字符串ByVal传递给API 函数就是这样做的方法,函数可以更改字符串的内容。它与[In]和[Out]无关,这些只是提示marshaler 跳过复制数据。