向dll函数传递某对象的无符号型地址

炮子枪 2011-01-14 02:41:36
C++:long (*func)(long eventType, unsigned long userParam)

这个函数其实是一个回调函数,就是说我c#代码调用dll中一个函数,

其中第二个参数“userParam”虽然是无符号整形,但他就是一个对象的内存起始地址,比如当前窗体的this的地址,这样回调函数回调时,能通过这个“userParam”来复原form类型,并可以做相应操作


但问题是:
(1)我怎么把form 的实例(或者某个类)转换成ulong给传递过去?
(2)回调时,我又怎么把这个表示内存地址的ulong转为form(或类)的实例对象?

...全文
234 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
xingyuebuyu 2011-01-14
  • 打赏
  • 举报
回复
c++中的long对应C#的int
xingyuebuyu 2011-01-14
  • 打赏
  • 举报
回复
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct SDK_Information
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string strInternalName;
public int format;
public int dataSize;
}
var structObj=new SDK_Information();
var size = Marshal.SizeOf(typeof(SDK_Information));
var structPtr = Marshal.AllocHGlobal(size);

//调用成功后数据就会存放到申请的以structPtr 地址开始的内存
SDK_ReadInfo(0, structPtr);

structObj=(SDK_Information)Marshal.PtrToStructure(structPtr,typeof(SDK_Information));

Marshal.FreeHGlobal(structPtr);


long (*func)(long eventType, unsigned long userParam)

试试对应到C#

int (*func)(int eventType, Form1 userParam)
第2个参数是一个对象,就直接定义为这个对象类型试试,让编译自已去尝试获取指针进行转换


炮子枪 2011-01-14
  • 打赏
  • 举报
回复
没关系,只是用var定义的变量让我觉得陌生

不过我试验了您的方法,得到的结果还是-1,倒是不出错误了,哎弄的我也不知道是怎么回事了
ShinNakoruru 2011-01-14
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 letsbetter 的回复:]
不过您用的是C#什么版本的,我用的是vs2005
[/Quote]

C# 4.0

VS2010

厄,跟这个有关系么??
炮子枪 2011-01-14
  • 打赏
  • 举报
回复
不过您用的是C#什么版本的,我用的是vs2005
ShinNakoruru 2011-01-14
  • 打赏
  • 举报
回复
调用方法肯定是我发的5楼那种方式,ref什么的肯定不对
炮子枪 2011-01-14
  • 打赏
  • 举报
回复
我把结构体改成这样
public struct SDK_Information
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public char[] strInternalName;
public long format;
public long dataSize;
}

然后用
SDK_Information pInfo;
pInfo.strInternalName = new char[32];
pInfo.format = 0;
pInfo.dataSize = 0;
sdk_readInfo(_PHCamera, 0, ref pInfo);

确跑出一个外部组件异常。
ShinNakoruru 2011-01-14
  • 打赏
  • 举报
回复
实在不行把结构体拷贝到内存再调用


var bytes = new byte[size];
Marshal.Copy(structPtr, bytes, 0, size);
var hdl=GCHandle.Alloc(bytes,GCHandleType.Pinned);
var ptr =hdl.AddrOfPinnedObject();

SDK_ReadInfo(0, ptr);

hdl.Free();


我也搞不懂这转来转去有啥意义……

总之你试试看
oneatree 2011-01-14
  • 打赏
  • 举报
回复
ulong i = (ulong)this.Handle;
以及
Form1 frm = (Form1)Form.FromHandle((IntPtr)i);
炮子枪 2011-01-14
  • 打赏
  • 举报
回复
楼上老兄的代码我调试了,返回的还是-1,结构体中也没有获得相应的值

用c++调用时么有错的
ShinNakoruru 2011-01-14
  • 打赏
  • 举报
回复
我没具体调用过,但貌似要传结构体也是得传指针
所以要这样:


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct SDK_Information
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string strInternalName;
public long format;
public long dataSize;
}
var structObj=new SDK_Information();
var size = Marshal.SizeOf(typeof(SDK_Information));
var structPtr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(structObj, structPtr, false);

SDK_ReadInfo(0, structPtr);

Marshal.FreeHGlobal(structPtr);
炮子枪 2011-01-14
  • 打赏
  • 举报
回复
谢谢,还有一个问题就是传递结构体的问题
C++中:
函数 SDK_ReadInfo(long readKind, SDK_Information * pImgInfo);
参数中pImgInfo是一个结构体,如下所示:
typedef struct {
char strInternalName[32];
long format;
long dataSize;
}SDK_Information;

然后我在c#中定义一个结构体
public struct SDK_Information
{
public string strInternalName;
public long format;
public long dataSize;
}
然后这样调用:
SDK_Information info;
info.strInternalName = "";
info.format = 0;
info.dataSize = 0;

SDK_ReadInfo(0, ref pImgInfo);

但执行后返回的是一个-1(错误,具体什么错误不清楚),而且info也没有获得应有的值。
请问这里有错误码?
bdmh 2011-01-14
  • 打赏
  • 举报
回复

ulong i = (ulong)this.Handle;
以及
Form1 frm = (Form1)Form.FromHandle((IntPtr)i);
炮子枪 2011-01-14
  • 打赏
  • 举报
回复
怎么再组合回来呢?就是ulong到this
bdmh 2011-01-14
  • 打赏
  • 举报
回复
直接转吧,类似
ulong i = (ulong)this.Handle;

111,118

社区成员

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

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

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