p/invoke 中 array of byte,用byte[]传值报错

maststt 2012-05-17 06:03:23
dll是delphi写的,某函数参数是array of byte,我用ref byte[],intptr,stringbuilder传过去我构建好的byte[],总是报内存读写错误。

请指教啊。。
...全文
452 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
WAN 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]
引用 14 楼 的回复:

Dephi要写出可供类C语言调用的dll要额外考虑更多问题,如果dll提供者没能提供VC调用例,我是不敢去信任它


你说的很有道理,我让对方改为pbyte试试。用pbyte的话,我这边是不是ref byte[]就对应了?
[/Quote]
仅仅是 byte[]
maststt 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]

Dephi要写出可供类C语言调用的dll要额外考虑更多问题,如果dll提供者没能提供VC调用例,我是不敢去信任它
[/Quote]

你说的很有道理,我让对方改为pbyte试试。用pbyte的话,我这边是不是ref byte[]就对应了?
WAN 2012-05-22
  • 打赏
  • 举报
回复
Dephi要写出可供类C语言调用的dll要额外考虑更多问题,如果dll提供者没能提供VC调用例,我是不敢去信任它
WAN 2012-05-22
  • 打赏
  • 举报
回复
array of byte貌似是Dephi定义的独特的数组类型,dll应该使用标准的C类型的数组,否则要准确的知道它在Dephi的实现方式,然后在C#中模拟它
建议这样:叫对方改接口,改PByte或者其它标准数据结构。要不然NND你给我个VC调用例啊,我可以自己改C#的!
maststt 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

delphi参数类型PByte
对应C#的ref byte[]
[/Quote]

原型是对方给我的,delphi写的,就是array of byte,不是pbyte。我ref byte[]过去就报内存读写错误。。

业务就是我组织一段byte[]扔给他处理,哪知道根本无法传递。。。不知道怎么解决,sigh
xky96 2012-05-18
  • 打赏
  • 举报
回复
delphi参数类型PByte
对应C#的ref byte[]
xky96 2012-05-18
  • 打赏
  • 举报
回复
VC的dll与delphi的dll原型定义是不同的,
不能套用VC的经验
qldsrx 2012-05-18
  • 打赏
  • 举报
回复
这是调用代码,可见那个ObjectHandleOnStack是用来处理byte[]返回值用的,连初始化都不需要,就可以获得一个非托管分配内存的字节数组了。

[SecuritySafeCritical]
public byte[] Encrypt(byte[] rgb, bool fOAEP)
{
if (rgb == null)
{
throw new ArgumentNullException("rgb");
}
this.GetKeyPair();
byte[] o = null;
EncryptKey(this._safeKeyHandle, rgb, rgb.Length, fOAEP, JitHelpers.GetObjectHandleOnStack<byte[]>(ref o));
return o;
}
qldsrx 2012-05-18
  • 打赏
  • 举报
回复
好像那个SizeConst不能加,我找了一个微软的dll的定义,你先看下,参考下:
[SuppressUnmanagedCodeSecurity, SecurityCritical, DllImport("QCall", CharSet=CharSet.Unicode)]
private static extern void DecryptKey(SafeKeyHandle pKeyContext, [MarshalAs(UnmanagedType.LPArray)] byte[] pbEncryptedKey, int cbEncryptedKey, [MarshalAs(UnmanagedType.Bool)] bool fOAEP, ObjectHandleOnStack ohRetDecryptedKey);

internal static class JitHelpers
{
// Fields
internal const string QCall = "QCall";

// Methods
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), SecurityCritical]
internal static ObjectHandleOnStack GetObjectHandleOnStack<T>(ref T o) where T: class
{
TypedReference reference = __makeref(o);
return new ObjectHandleOnStack(reference.GetPointerOnStack());
}
//部分代码省略
}
[StructLayout(LayoutKind.Sequential)]
internal struct ObjectHandleOnStack
{
private IntPtr m_ptr;
internal ObjectHandleOnStack(IntPtr pObject)
{
this.m_ptr = pObject;
}
}




maststt 2012-05-18
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

delphi的原型是啥?你用C++调用报错吗?
[/Quote]

原型形参就是array of byte
qldsrx 2012-05-18
  • 打赏
  • 举报
回复
delphi的原型是啥?你用C++调用报错吗?
maststt 2012-05-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

这是调用代码,可见那个ObjectHandleOnStack是用来处理byte[]返回值用的,连初始化都不需要,就可以获得一个非托管分配内存的字节数组了。
C# code

[SecuritySafeCritical]
public byte[] Encrypt(byte[] rgb, bool fOAEP)
{
if (rgb == null)
{
thro……
[/Quote]

不得行,那只是传个intptr,还是报错
maststt 2012-05-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

去掉ref 看看
我估计是delphi操作了byte[]数组
[/Quote]

你声明的这个invoke,会报MarshalAs(UnmanagedType.ByValArray, SizeConst = 256只能用在struct的声明中,不能用在参数的声明中
maststt 2012-05-17
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
dll是delphi写的,某函数参数是array of byte,我用ref byte[],intptr,stringbuilder传过去我构建好的byte[],总是报内存读写错误。

请指教啊。。
[/Quote]

之前就试过了,加了ref报内存错误,不加ref报引擎错误
qldsrx 2012-05-17
  • 打赏
  • 举报
回复
我记得要将托管对象传递给非托管函数调用,在C#中还必须固定地址才行,对于值类型,因为只是值传递,因此不需要固定内存地址,但是数组就不同了,用过指针的都知道fixed关键字,为了防止内存被动态回收,而函数参数传递则是用MarshalAs来固定,例如:
[DllImport("XXX.DLL", CharSet = CharSet.Auto)]
static extern int testBytes([MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]byte[] bytes);
anzhiqiang_touzi 2012-05-17
  • 打赏
  • 举报
回复
去掉ref 看看
我估计是delphi操作了byte[]数组

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧