【发布时间】:2017-09-06 10:08:22
【问题描述】:
我有一个从 .dll 调用的 C# 方法
[DllImport("somedll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int find([MarshalAs(UnmanagedType.AnsiBStr, SizeConst = 64)] string atr, out IntPtr int);
[DllImport("somedll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int getData(IntPtr int, int dataId, byte[] dataBuffer, ref int dataBufferSize);
在 C# 中调用此方法如下所示
static IntPtr number = IntPtr.Zero;
static int res = 0;
try{
number = IntPtr.Zero;
res = find(null, out number);
if (number == IntPtr.Zero)
throw new ApplicationException("Something is wrong");
uint dataBufferSize = 1024;
res = getData(number, 1, null, ref dataBufferSize);
}
我没有找到 Java 中的等价物。
如果我这样做:
public int find(String atr, Pointer int);
上面写着
java.lang.Error: Invalid memory access
at com.sun.jna.Native.invokeInt(Native Method)
at com.sun.jna.Function.invoke(Function.java:419)
at com.sun.jna.Function.invoke(Function.java:354)
at com.sun.jna.Library$Handler.invoke(Library.java:244)
如果我这样做:
public int find(String atr, IntByReference int);
什么都没有发生。
Java 代码
IntByReference iref = new IntByReference();
res = find(null, iref);
Pointer pointer = iref.getPointer();
int dataBufferSize = 1024;
byte[] dataBuffer = new byte[dataBufferSize];
res = getData(Pointer.nativeValue(pointer), 1, dataBuffer, dataBufferSize);
find 返回 0 表示 OK,但 getData 返回 6 表示内存地址不好。什么都没发生,我的意思是除 0 以外的任何其他 res。
【问题讨论】:
-
那么,也许您应该删除 C# 标签并添加 JNI 或 JNA 标签?
-
(我的意思是,您根本不必添加任何标签,如果您愿意,您甚至可以使用完全误导性的标签,但是可能能够提供答案的人可能会没有看到你的问题。)
-
@kennytm 这不是这个问题的有效副本
-
IntPtr在 32 位系统上是 32 位,在 64 位系统上是 64 位,您可能正在寻找NativeLongByReference代替(尽管我不确定它在 Windows 上的行为)。