【发布时间】:2016-04-05 15:10:54
【问题描述】:
我正在开发一个包装库,允许我的项目在任何 CPU 环境中使用 x86 C++ dll 库,我无法控制 dll,因此我在 C# 中使用 DllImport。
在 C++ 中声明了一个提供的函数: int __stdcall Func(int V, unsigned char *A) 并在VB中提供了一个示例声明:Private Declare Function Func Lib "lib.dll" Alias "_Func@8" (ByVal V As Long, A As Any) As Long
此函数将请求设备通过将 Convert.ToInt64(decimalValue) 作为 V 传递给卡/从卡中添加/减去一个值,并在 A 中传递一些自定义信息。
这里是A的描述:
- 它是一个包含 7 个字节的字节指针。
- 前 5 个字节用于存储将传递到卡日志的信息(收据编号的后 4 位应包含在前 2 个字节中,其他 3 个可能是 A3A4A5)
- 最后 2 个字节用于存储将传递给设备的信息(收据编号的最后 4 位)
- 返回时,A 包含一个 32 字节的数据。
经过数小时的研究和尝试,除了“访问冲突异常”之外,我无法得出其他结果。请参阅以下代码草案:
[DllImport("lib.dll", EntryPoint="_Func@8")]
public static external Int64 Func(Int64 V, StringBuilder sb);
string ReceiptNum = "ABC1234";
decimal Amount = 10m;
byte[] A = new byte[32];
A[0] = Convert.ToByte(ReceiptNum.Substring(3, 2));
A[1] = Convert.ToByte(ReceiptNum.Substring(5));
A[2] = Convert.ToByte("A3");
A[3] = Convert.ToByte("A4");
A[4] = Convert.ToByte("A5");
A[5] = Convert.ToByte(ReceiptNum.Substring(3, 2));
A[6] = Convert.ToByte(ReceiptNum.Substring(5));
StringBuilder sb = new StringBuilder(
new ASCIIEncoding().GetString(A), A.Length
);
Int64 Result = Func(Convert.ToInt64(Amount), sb);
此时它会抛出异常。我尝试过传递 IntPtr、byte*、byte (by A[0])、byval、byref,但它们都不起作用。 (也尝试部署为 x86 CPU)
不胜感激!感谢您的宝贵时间!
PS - 使用 StringBuilder 的原因是该库包含一个接受“char *Data”参数的函数,导致相同的异常,解决方案是使用 StringBuilder 作为指针传递,该函数的 VB 声明为:Private声明 Function Func1 Lib "lib.dll" Alias "_Func1@12(ByVal c As Byte, ByVal o As Byte, ByVal Data As String) As Long
【问题讨论】:
-
请记住,
ASCIIEncoding仅支持 7 位字符,因此它不会返回十六进制值0xA3、0xA4或0xA5。Convert.ToByte(string)也只处理十进制数字 0-9;Convert.ToByte("A3")将抛出 FormatException。所以我不知道你是怎么打电话给Func()的。 -
嗨,迈克尔!由于我现在无法连接到我的办公室开发服务器,所以我只是从内存中编写代码,将尝试 Luaan 解决方案 tmr:)
标签: c# c++ .net dll access-violation