社区
C#
帖子详情
C#调用C++:DLL的long类型参数“方法的类型签名与 PInvoke 不兼容错误”
fellowcheng
2005-01-17 03:25:33
如题
...全文
467
14
打赏
收藏
C#调用C++:DLL的long类型参数“方法的类型签名与 PInvoke 不兼容错误”
如题
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
14 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
fellowcheng
2005-01-20
打赏
举报
回复
算了,用VB6做吧
虽然没有解决,但还是非常感谢YvesGao(叶辉)的热心帮助
fellowcheng
2005-01-19
打赏
举报
回复
再顶一下
YvesGao
2005-01-19
打赏
举报
回复
我利用你的那个dll自己做了一个C#的sln
果然出错,是那个方法的类型签名与 PInvoke 不兼容错误
我仔细一看才发现 原来 DeviceInfo 返回的是一个结构体 而不是一个结构体指针
我研究P/Invoke是用来调用win32api,win32api中传递的都是结构体指针,至少我所看的这些资料上是这样的,这种 返回值的类型 是结构体(它代表一块非托管内存)的情况我从未遇见过,我在msdn上查到的资料,也没说如何处理这种情况,我也感到很困惑,为什么不能封送处理一整块内存。
我研究了一早晨也没想到办法,我想可能要问问别的做过这方面研究的朋友了,
我猜想也许需要自定义封送处理?
我也想到一个变通的方法,供你参考,你可以写一个dll,这个dll导出一个DeviceInfoWrapper函数,它提供一个传出参数 是 指向devinfo的结构体指针,这个函数内部再调用Prr803xLib.dll的DeviceInfo。我的意思就是在非托管代码中将DevInfo结构转换成指针再传递给P/Invoke。
除此之外,我实在没招了,:(
我在写一个关于P/Invoke 的论文,看来你给我找了点可以写的东西,如果我研究明白的话,呵呵
YvesGao
2005-01-19
打赏
举报
回复
下午,又去查了MSDN,确切地找到了这个主题,但是没有解决方法,有很多关于结构体作为参数传递的情况及解决方法(11种之多),但就是没有结构体作为返回值的情况,非常诧异,难道是微软疏漏了?
我看你写个wrapper吧
fellowcheng
2005-01-19
打赏
举报
回复
还有没有人help
mm521
2005-01-18
打赏
举报
回复
c#的long是64位吧
快速开始中有些例子
fellowcheng
2005-01-18
打赏
举报
回复
up
YvesGao
2005-01-18
打赏
举报
回复
出的什么错,错误信息是什么?
如果方便的话,把这个C#的解决方案,就这个最小的就可以,能说明问题就可以了,发给我
fellowcheng
2005-01-18
打赏
举报
回复
函数原型:
#ifndef _GLOBALS_H_
#define _GLOBALS_H_
#define DllImport __declspec(dllimport)
struct DetectLableMode
{
char *DetectLable;
int LableNum;
}strDetectLableMode;
struct DevInfo
{
char Sw_Rev[50];
char D_Rev[50];
char Hw_Type[50];
char Sw_Type[50];
char Tr_Type[50];
} strDevInfo;
extern "C" DllImport HANDLE __stdcall OpenCom(int nPort,long nBaudRate,
int nParity,
int nDataBits,int nStopBit,
int nFlowCtl);
extern "C" DllImport void __stdcall CloseCom(HANDLE hComm);
extern "C" DllImport char* __stdcall SetAntenna(HANDLE hComm,BYTE Addr, BOOL bStats);
extern "C" DllImport DetectLableMode __stdcall DetectTagUID(HANDLE hComm,BYTE Addr,
BOOL Tag = 0);
extern "C" DllImport BOOL __stdcall ReadTagData(HANDLE hComm,
BYTE Addr, BYTE Mode,BYTE *UID,
BYTE BlockAddr,BYTE nBlockNum,
char *ReadData);
extern "C" DllImport DevInfo __stdcall DeviceInfo(HANDLE hComm, BYTE Addr);
extern "C" DllImport BOOL __stdcall DetectBaud(HANDLE hComm,BYTE Addr);
extern "C" DllImport char* __stdcall GetSysInfo(HANDLE hComm,
BYTE Addr, BYTE Mode, BYTE *UID);
extern "C" DllImport BOOL __stdcall WriteTagAFI(HANDLE hComm, BYTE Addr, BYTE Mode,
BYTE *UID, BYTE NewAFI);
extern "C" DllImport BOOL __stdcall LockTagAFI(HANDLE hComm, BYTE Addr, BYTE Mode,
BYTE *UID);
extern "C" DllImport BOOL __stdcall WriteTagDSFID(HANDLE hComm, BYTE Addr, BYTE Mode,
BYTE *UID, BYTE NewDSFID);
extern "C" DllImport BOOL __stdcall LockTagDSFID(HANDLE hComm, BYTE Addr, BYTE Mode,
BYTE *UID);
extern "C" DllImport BOOL __stdcall WriteSingleBlock(HANDLE hComm,
BYTE Addr, BYTE Mode,BYTE *UID,BYTE BlockAddr,
BYTE *WriteData);
extern "C" DllImport BOOL __stdcall CheckSingleTagBlockStatus(
HANDLE hComm,BYTE Addr, BYTE Mode,
BYTE *UID, BYTE BlockAddr,
int nBlockNum,char *Stats);
extern "C" DllImport char* __stdcall LockTagBlocks(HANDLE hComm, BYTE Addr, BYTE Mode,
BYTE BeginBlock, BYTE Blocks, BYTE *UID);
#endif
fellowcheng
2005-01-18
打赏
举报
回复
先谢谢YvesGao(叶辉)的热心帮助!!
不过还没成功呀!
[DllImport("Prr803xLib.dll",EntryPoint= "OpenCom")]
public static extern IntPtr OpenCom(Int32 nPort,Int32 nBaudRate,Int32 nParity,Int32 nDataBits,Int32 nStopBit,Int32 nFlowCtl);
[DllImport("Prr803xLib.dll",EntryPoint="CloseCom")]
public static extern void CloseCom(Int32 nPort);
[DllImport("Prr803xLib.dll",EntryPoint = "DeviceInfo")]
public static extern DevInfo DeviceInfo(IntPtr hCom,Byte Addr);
public struct DevInfo
{
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 50)]
public string Sw_Rev;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 50)]
public string D_Rev;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 50)]
public string Hw_Type;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 50)]
public string Sw_Type;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 50)]
public string Tr_Type;
}
调用代码如下:
private void btOpenPort_Click(object sender, System.EventArgs e)
{
try
{
IntPtr hCom= OpenCom(2,9600, 2, 8, 0, 0);
m_DevInfo = DeviceInfo(hCom,0); //这里出错!!
this.txtDeviceInfo.Text+="\n"+m_DevInfo.Sw_Rev;
}
catch(Exception ept)
{
this.txtDeviceInfo.Text+="\n"+ept.Message;
}
finally
{
CloseCom(2);
}
}
YvesGao
2005-01-18
打赏
举报
回复
我看了DeviceInfo 的函数原型为:
extern "C" DllImport DevInfo __stdcall DeviceInfo(HANDLE hComm, BYTE Addr);
所以应是你在C#中的映射原型写错了,应为:
[DllImport("Prr803xLib.dll" ,EntryPoint = "DeviceInfo")]
public static extern DevInfo DeviceInfo(System.IntPtr hComm, byte Addr);
HANDLE 的类型为void* 对应于托管的System.IntPtr
另外,DevInfo结构的原型为:
struct DevInfo
{
char Sw_Rev[50];
char D_Rev[50];
char Hw_Type[50];
char Sw_Type[50];
char Tr_Type[50];
} strDevInfo;
在C#中的映射类型为:
struct DevInfo
{
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 50)]
public string Sw_Rev;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 50)]
public string D_Rev;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 50)]
public string Hw_Type;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 50)]
public string Sw_Type;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 50)]
public string Tr_Type;
}
这些都属于一类P/Invoke问题,如果不是很清楚的话,可以先花一点时间,查看相关资料,然后就迎刃而解了,推荐一篇文章,相信能够帮到你,原始出处是MSDN magazine
http://blog.csdn.net/web_gus/archive/2004/10/26/152622.aspx
另外,下面这个帖子上也有一些相关资料,可以供进一步学习之用
http://community.csdn.net/Expert/topic/3708/3708210.xml?temp=.963772
YvesGao
2005-01-17
打赏
举报
回复
Prr803xLib.dll
中的函数原型是什么?有没有c的声明?
在VB5中Long是32位的么?
解决这类问题,关键在于跟踪数据在托管和非托管代码中的表示形式,
我也在研究P/Invoke方面的一些问题,不如提供多一些的信息,我来看看。
fellowcheng
2005-01-17
打赏
举报
回复
up
fellowcheng
2005-01-17
打赏
举报
回复
VB5.0:
Public Declare Function DeviceInfo Lib "Prr803xLib.dll" (ByVal hCom As Long, ByVal Addr As Byte) As DevInfo
C#中:
[DllImport("Prr803xLib.dll")]
public static extern DevInfo DeviceInfo(int hCom,byte Addr);
C#
与
C++
转换
本文将重点探讨这两种
方法
,并详细介绍如何通过P
Invoke
实现在Visual Studio 2010环境下
C#
调用
C++
动态链接库(
DLL
)的具体步骤。 #### 二、
C#
与
C++
交互
方法
概述 ##### 1. 使用
C++
/CLI作为代理中间层 这种
方法
的核心...
C#
的核心问题-编译器-如何使用
C++
的
DLL
.rar
本文将深入探讨如何在
C#
项目中
调用
C++
编写的动态链接库(
DLL
),以此来实现
C#
与
C++
的混合编程。首先,我们需要理解
C#
和
C++
之间的差异以及如何通过
DLL
来桥接这两种语言。
C#
是一种面向对象的、
类型
安全的编程语言,...
p
invoke
-stack-bug:由输出
参数
中的结构打包导致的P
Invoke
错误
的演示代码,将覆盖不相关的堆栈变量
2. **数据
类型
映射**:
C#
和C/
C++
的数据
类型
不完全相同,例如,
C#
的`int`对应C的`int32`,`
long
`对应`int64`等。结构体成员的
类型
也要正确映射。 3. **结构体布局**:
C#
中的结构体默认是值
类型
,它们在栈上分配,而C...
C#
版封装的Windows API
- **
参数
类型
转换**:由于
C#
和Windows API的
参数
类型
不完全一致,需要进行相应的
类型
转换。例如,`IntPtr`用于表示无符号整型指针,`string`对应API的字符数组。 - **
错误
处理**:
调用
API可能会出现异常,应使用`...
C#
完全手册
- **语法**:如何使用
方法
签名
(包括返回
类型
、
方法
名、
参数
列表)来声明
方法
。 #### 11.2
方法
中的
参数
- **
类型
**:
参数
可以是值
类型
、引用
类型
或out、ref
参数
。 - **传递方式**:
参数
可以按值传递或按引用传递...
C#
111,092
社区成员
642,554
社区内容
发帖
与我相关
我的任务
C#
.NET技术 C#
复制链接
扫一扫
分享
社区描述
.NET技术 C#
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
让您成为最强悍的C#开发者
试试用AI创作助手写篇文章吧
+ 用AI写文章