C#如何调用C++中结构函数指针调用

描绘,更多精彩;缔造,一个神话!
字号:大 中 小
1. 不返回值的参数C++ 原型:bool& & SendNewSms(char *szTel, char *szMessage);C#引用;[DllImport( "CdmaCard.dll",EntryPoint="SendNewSms")]public& & static& & extern& & bool SendNewSms(string phone,string msg);2. 带返回值(char *)C++原型:BOOL GetCardErrorMessage(char *szErrorMessage , int errorCode);C#引用[DllImport( "CdmaCard.dll",EntryPoint="GetCardErrorMessage")]& & public& & static& & extern& & int GetCardErrorMessage(StringBuilder msg,int errorCode);StringBuilder buf = new StringBuilder(1024);//指定的Buf大小必须大于可能的最大长度& & & GetCardErrorMessage(buf,1);3. 带返回值(其他类型)C++原型:& BOOL GetSmsSaveStation (int *nSmsStation);C#引用& [DllImport( "CdmaCard.dll",EntryPoint="GetSmsSaveStation")]& & public& & static& & extern& bool GetSmsSaveStation(ref int nStation);4. 传递结构体指针(C++填充)C++原型:struct NET_INFO_STRUCT{& DWORD nDurationT //持续时间&& double nReceiveB //接收字节& double nSendB& //发送字节};&&BOOL NetGetConnectDetail(NET_INFO_STRUCT *lpNetInfo);C#引用&&public struct NET_INFO_STRUCT{& public uint nDurationT //持续时间&& public double nReceiveB //接收字节& public double nSendB& //发送字节}[DllImport( "CdmaCard.dll",EntryPoint="NetGetConnectDetail")]& & & & public& & static& & extern& int NetGetConnectDetail(ref NET_INFO_STRUCT pNetInfo);& & & &&& & & & NET_INFO_STRUCT netInfo = new NET_INFO_STRUCT();& & & & NetGetConnectDetail(ref netInfo);&& & & &&5. 传递结构体数组(C++来填充)C++原型:struct UIM_BOOK_STRUCT{& int UimI& char szName[15];& char szPhone[21];};int ReadUimAllBook(UIM_BOOK_STRUCT lpUimBookItem[],int nMaxArraySize);C#引用[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]//可以指定编码类型public struct UIM_BOOK_STRUCT{& public int UimI& [MarshalAs(UnmanagedType.ByValTStr, SizeConst= 15)]& public string szN& [MarshalAs(UnmanagedType.ByValTStr, SizeConst= 21)]& public string szP};[DllImport( "CdmaCard.dll",EntryPoint="ReadUimAllBook")]public& & static& & extern& int ReadUimAllBook( UIM_BOOK_STRUCT [] lpUimBookItem,int nMaxArraySize);UIM_BOOK_STRUCT[] p = new UIM_BOOK_STRUCT[20];int ret = ReadUimAllBook(p,p.Length);6. 注意类型不一致,会导致调用失败,(1) long 类型,在C++中是4字节的整数,在C#中是8字节的整数;(2) 字符串类型的设置不正确;
function open_phone(e) {
var context = document.title.replace(/%/g, '%');
var url = document.location.
open("http://go.10086.cn/ishare.do?m=t&u=" + encodeURIComponent(url) + "&t=" + encodeURIComponent(context) + "&sid=70cd6ed4a0");
!觉得精彩就顶一下,顶的多了,文章将出现在更重要的位置上。
请根据下图中的字符输入验证码:
(您的评论将有可能审核后才能发表)
已成功添加“”到
请不要超过6个字18:16 提问
C# 调用c++函数 结构体 指针
求大神解答下,
c++结构体:
typedef struct
Byte byRW;
typedef struct
PACKET *pP
INT32 iNumP
c++ 函数申明:
BOOL Transfer(BLOCK block);
C#如何调用这个Transfer函数:
1:定义C#结构体
public struct PACKET
byte byRW;
那么另个结构体BLOCK在C#中怎么定义???
2. 定义完后如何调用(DllImport这个我知道),其他有什么特殊设置????
按赞数排序
这个也太长了吧...
这个也太长了吧...
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐C#如何调用C++的DLL的结构体数组指针
[问题点数:40分,结帖人liyi212]
C#如何调用C++的DLL的结构体数组指针
[问题点数:40分,结帖人liyi212]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2012年 总版技术专家分年内排行榜第一
2013年 总版技术专家分年内排行榜第七2011年 总版技术专家分年内排行榜第五2009年 总版技术专家分年内排行榜第九
匿名用户不能发表回复!|博客分类:
因为公司一直都是做C++开发的,因客户需要要提供C#版本接口,研究了一下C#,发现其强大简洁, 在跨语言调用方面封装的很彻底,提供了强大的API与之交互.这点比JNA方便多了. Java与C#都只能调用C格式导出动态库,因为C数据类型比较单一,容易映射. 两者都是在本地端提供一套与之映射的C#/java描述接口,通过底层处理这种映射关系达到调用的目的.
一. 结构体的传递
#define JNAAPI extern "C" __declspec(dllexport) // C方式导出函数
typedef struct
int majorV
int minorV
int buildN
int platFormId;
char szVersion[128];
// 1. 获取版本信息(传递结构体指针)
JNAAPI bool GetVersionPtr( OSINFO *info );
// 2.获取版本信息(传递结构体引用)
JNAAPI bool GetVersionRef(OSINFO &info);
可以通过二种方式来调用:
// OSINFO定义
[StructLayout(LayoutKind.Sequential)]
public struct OSINFO
public int osV
public int majorV
public int minorV
public int buildN
public int platFormId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szV
1. 方式一(传入结构体引用),在C#中,结构体是以传值方式传递,类才是以传地址方式传递,加关键字ref即可. C端传递了两种不同类型的参数,都可以通过引用来解决.
[DllImport("jnalib.dll", EntryPoint = "GetVersionPtr")]
public static extern bool GetVersionPtr(ref OSINFO info);
public static extern bool GetVersionRef(ref OSINFO info);
2. 方式二(传入IntPtr(平台通用指针))
IntPtr pv = Marshal.AllocHGlobal(148); //结构体在使用时一定要分配空间(4*sizeof(int)+128)
Marshal.WriteInt32(pv,148); //向内存块里写入数值
if (GetVersionPtr(pv)) //直接以非托管内存块地址为参数
Console.WriteLine("--osVersion:{0}", Marshal.ReadInt32(pv, 0));
Console.WriteLine("--Major:{0}",Marshal.ReadInt32(pv, 4)); //移动4个字节
Console.WriteLine("--BuildNum: " + Marshal.ReadInt32(pv, 12));
Console.WriteLine("--szVersion: "+Marshal.PtrToStringAnsi((IntPtr)(pv.ToInt32()+20)));
Marshal.FreeHGlobal(pv); //处理完记得释放内存
二.结构体数组的传递
// 传递结构体指针
JNAAPI bool GetVersionArray(OSINFO *info,int nLen);
* C#接口,对于包含数组类型,只能传递IntPtr
[DllImport("jnalib.dll", EntryPoint = "GetVersionArray")]
public static extern bool GetVersionArray(IntPtr p, int nLen);
// 源目标参数
OSINFO[] infos = new OSINFO[2];
for (int i = 0; i & infos.L i++)
infos[i] = new OSINFO();
IntPtr[] ptArr = new IntPtr[1];
ptArr[0] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(OSINFO)) * 2); //分配包含两个元素的数组
IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(OSINFO)));
Marshal.Copy(ptArr, 0, pt, 1); //拷贝指针数组
GetVersionArray(pt, 2); //调用
//还原成结构体数组
for (int i = 0; i & 2; i++)
infos[i]=(OSINFO)Marshal.PtrToStructure((IntPtr)(pt.ToInt32()+i*Marshal.SizeOf(typeof(OSINFO))),typeof(OSINFO));
Console.WriteLine("OsVersion:{0} szVersion:{1}", infos[i].osVersion, infos[i].szVersion);
三. 复杂结构体的传递
1. 输出参数,结构体作为指针传出
typedef struct
char name[20];
double scores[30];
// Class中包含结构体数组类型
typedef struct
Student students[50];
// 传入复杂结构体测试
JNAAPI int GetClass(Class *pClass,int len);
// 接口定义
[DllImport("jnalib.dll", EntryPoint = "GetClass")]
public static extern int GetClass(IntPtr pv,int len);
// 结构体定义
// Student
[StructLayout(LayoutKind.Sequential)]
public struct Student
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=20)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
public double[]
[StructLayout(LayoutKind.Sequential)]
public struct Class
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)] // 指定数组尺寸
public Student[] // 结构体数组定义
// 调用复杂结构体测试
int size = Marshal.SizeOf(typeof(Class)) * 50;
IntPtr pBuff = Marshal.AllocHGlobal(size); // 直接分配50个元素的空间,比Marshal.copy方便多了
GetClass(pBuff, 50);
Class[] pClass = new Class[50];
for (int i = 0; i & 50; i++)
IntPtr ptr = new IntPtr(pBuff.ToInt64() + Marshal.SizeOf(typeof(Class)) * i);
pClass[i] = (Class)Marshal.PtrToStructure(ptr, typeof(Class));
Marshal.FreeHGlobal(pBuff); // 释放内存
2. 输入参数, 给复杂结构体赋值后作为输入参数传入
对于比较大的结构体指针,无法直接应用结构体类型,转化成IntPtr类型, 此时需要将原生类型转化为指针,并给指针赋值
调用方法: Marshal.StructureToPtr(stu, ptr1, true)
浏览 23572
我碰到一个结构体,怎么传进去都是有问题,报未将对象引用,我的QQ是6439214,能联系么结构体是否未new,未实例化容易出现该错误
浏览: 402886 次
来自: 深圳
陈宇飞 写道reset()为什么不可以用了,版本低了,还是头文 ...
reset()为什么不可以用了,版本低了,还是头文件呢
环形缓冲区类(C++源码)绝对可用.....转到你网易的微博上 ...
tadpole_java 写道经常看看您的帖子,把它当成教科书 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'没有更多推荐了,
不良信息举报
举报内容:
C#调用带结构体指针的C Dll的方法
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!

我要回帖

更多关于 父类指针调用子类函数 的文章

 

随机推荐