首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

(最高难度)C#调用c++ DLL(返回结构数组指针) ,顶者有分!解决方案

2012-01-28 
(最高难度)C#调用c++ DLL(返回结构数组指针) ,顶者有分!如何把返回c++结构数组指针,c#结构数组??请大侠帮

(最高难度)C#调用c++ DLL(返回结构数组指针) ,顶者有分!
如何把返回c++结构数组指针,c#结构数组??   请大侠帮助

c++定义:
QUERY*QueryTransactionHistory(DWORD   dwIP,int   nPort,TRANSACTION   *   ,int*   outNum,int*   nErrorCode);

TRANSACTION结构:
typedef   struct   TRANSACTION
{
characcount[19];
intmaxNum;
charstartDate[16];
charendDate[16];
}TRANSACTION;

QUERY结构:
typedef   struct   QUERY
{
intid;
intitemAmount;
intgold;
intsilver;
charitemName[30];
}QUERY;



[解决办法]
关注
[解决办法]
调一下先...
[解决办法]
ding
[解决办法]
帮顶
[解决办法]
帮顶
[解决办法]
帮顶
[解决办法]
//QUERY*QueryTransactionHistory(DWORD dwIP,int nPort,TRANSACTION * ,int* outNum,int* nErrorCode);

class TRANSACTION
{
publiccharaccount[19];
publicintmaxNum;
publiccharstartDate[16];
publiccharendDate[16];
}

class QUERY
{
publicintid;
publicintitemAmount;
publicintgold;
publicintsilver;
publiccharitemName[30];
}

[DllImport( "你的dll.dll ", CharSet=CharSet.Ansi)]
public static extern QUERY QueryTransactionHistory(string dwIP, int nPort, ref TRANSACTION TR, ref int outNum, ref int nErrorCode);
[解决办法]
记得加

using System.Runtime.InteropServices;
[解决办法]
学习
[解决办法]
关注

[解决办法]
[DllImport( "你的dll.dll ", CharSet=CharSet.Ansi)]
public static extern QUERY[] QueryTransactionHistory(string dwIP, int nPort, ref TRANSACTION TR, ref int outNum, ref int nErrorCode);

建议封装成com组件,使用更加方便。。。。
[解决办法]
:)

忘了是返回数组:)

QUERY[]
[解决办法]
帮顶
[解决办法]
学习学习
[解决办法]
继续关注
[解决办法]
不懂,顶一下
[解决办法]
学习
[解决办法]
mark
[解决办法]
以前好像有人问过。帮顶一下!
[解决办法]
呵呵,如果没错的话,以前那个人应该是我
现在来学习一下,哪位来指点下
[解决办法]
现在来学习一下,哪位来指点下



[解决办法]
学习!
[解决办法]
帮顶
[解决办法]
1. 因为返回的数组是变长的,所以DllImport函数声明不能用数组作返回类型。
必须使用IntPtr指针做返回值,然后用Marshal.PtrToStructure读取结构内容。

2. 如果你在C代码中用malloc申请的返回内存,那么记得提供一个释放该内存的C函数,否则会有内存泄漏。如果用的事WindowsAPI,可以再C#中用Marshal.FreeHGlobal释放。

下面是代码:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public class TRANSACTION
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 19)]
public string account;

public int maxNum;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string startDate;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string endDate;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class QUERY
{
public int id;
public int itemAmount;
public int gold;
public int silver;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)]
public string itemName;
}

class Program
{
[DllImport( "CPPDLL.DLL ", CallingConvention = CallingConvention.StdCall)]
public extern static IntPtr QueryTransactionHistory(uint swIP, int nPort, TRANSACTION pTran, out int cnt, out int nErrCode);

static void Main(string[] args)
{
int cnt, errCode;
TRANSACTION tran = new TRANSACTION();

tran.account = "account ";
tran.endDate = "endDate ";
tran.startDate = "startDate ";
tran.maxNum = 50;

//get retrun value as IntPtr
IntPtr ptr = QueryTransactionHistory(0, 0, tran, out cnt, out errCode);
Console.WriteLine( "============ CS =============== ");
Console.WriteLine( "Count = {0}, errCode = {1} ", cnt, errCode);

IntPtr head = ptr;
for (int i = 0; i < cnt; ++i)
{
//extract struct from pointer
QUERY q = (QUERY)Marshal.PtrToStructure(ptr, typeof(QUERY));
Console.WriteLine( "id = {0}, gold = {1}, silver = {2}, itemAmount = {3}, itemName = {4} ",
q.id, q.gold, q.silver, q.itemAmount, q.itemName);

//move pointer by sizeof(QUERY) to the next one
//WARNING: assume 32 bit machine!!!!!!
ptr = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(typeof(QUERY)));
}
//TODO: need to free memory
}
}
[解决办法]
六六顺啊,八匹马啊,哥俩好啊,七财美酒,四季发财,顶中你啊。

LZ说话要算话哦,顶者有分的哦。
[解决办法]
顶!

这也叫最高难度?
[解决办法]
路过
[解决办法]
佩服
[解决办法]
给一个必杀的提示,参数全部用byte[]或byte*这样可以得到参数的二进制信息,结构的内存分布是有规律可循的,你可以按照从这个二进制串和结构分布规律还原出结构中的各个成员,我曾经用过这招,必杀
------解决方案--------------------


这种问题还是顶顶算了。
[解决办法]

[解决办法]
佩服


[解决办法]
呵呵,顶~~
[解决办法]
帮顶
[解决办法]
up
[解决办法]
确实不好搞,我前两天才搞好了C#与com互相传递IStream
帮顶
[解决办法]
标记,留名。
顶一下,关注此问题。
[解决办法]

[解决办法]
帮顶
帮顶
帮顶
帮顶
帮顶
帮顶

[解决办法]
找到,好不容易找到了,请高手多说几句,这对于CS类的开发太有用了。请进一步说说,先谢过了。
[解决办法]
这里是我的C++ DLL代码,和上面的C#测试过没有问题。
你得C++一边的代码是怎么实现的?

typedef struct TRANSACTION
{
characcount[19];
intmaxNum;
charstartDate[16];
charendDate[16];
} TRANSACTION;

typedef struct QUERY
{
intid;
intitemAmount;
intgold;
intsilver;
charitemName[30];
}QUERY;

extern "C " _declspec(dllexport) QUERY* QueryTransactionHistory(DWORD dwIP,int nPort,TRANSACTION * pTran, int* outNum,int* nErrorCode) {
cout < < "dwIP = " < < dwIP < < ", nPort = " < < nPort < < ", pTran -> maxNum = " < < pTran -> maxNum < < endl;
cout < < "pTran -> account = " < < pTran -> account < < ", pTran -> startDate = " < < pTran -> startDate < < ", pTran -> endDate = " < < pTran -> endDate < < endl;

QUERY* ret = (QUERY* )malloc(sizeof(QUERY) * 2);
ret[0].id = 0;
ret[0].gold = ret[0].silver = ret[0].itemAmount = 1;
strcpy(ret[0].itemName, "Item0 ");

ret[1].id = 1;
ret[1].gold = ret[1].silver = ret[1].itemAmount = 2;
strcpy(ret[1].itemName, "Item1 ");

(*outNum) = 2;
(*nErrorCode) = 0;
return ret;
}

[解决办法]
学习 顶!!
[解决办法]
up
[解决办法]
mark
[解决办法]
mark
[解决办法]
结构要用引用来传,因为在C++中它其实是一个指针
[解决办法]
帮顶.
[解决办法]
有趣!

热点排行