C#调用C ++ dll返回列表 [英] C # to call C ++ dll return list
本文介绍了C#调用C ++ dll返回列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想成为C#调用和返回列表的C ++ DLL,类型是定义的结构
c ++结构是;
I want to be a C ++ DLL for C # call and return list, type is a structure defined
c ++ The structure is;
struct mailInfo
{
const char *mailFrom;
const char *mailReceivers;
const char *mailDate;
const char *mailTitle;
const char *mailBody;
}
;
C ++代码是:
;
C ++ code is:
extern "C" __declspec(dllexport) vector<mailInfo> rData(char module_path[],char tableName[])
{
mailInfo mailIo;
int result = sqlite3_open(((string)module_path+"\\mail.db").c_str(), &conn);
if (!result)
{
sqlite3_stmt *stat;
const char *pzTail = NULL;
sqlcommand="select * from "+(string)tableName+";";
sqlite3_prepare(conn, sqlcommand.c_str(), -1, &stat, &pzTail);
int nColumn = sqlite3_column_count(stat);
result = sqlite3_step(stat);
while (result == SQLITE_ROW) /* sqlite3_step() has another row ready */
{
//*(p+1) = '\0';
mailIo= outputItem(stat, nColumn, module_path);
mInfoList.push_back(mailIo);
//mlist.push_back(mailIo);
/*mInfo.mailFrom= (const char*)sqlite3_column_text(stat,2);
string ss=mInfo.mailFrom;
MessageBox(NULL,ss.c_str(),"send",MB_OK);*/
cout << endl;
result = sqlite3_step(stat);
}
return mInfoList;
}
结构在C#中定义:
The structure is defined in C #:
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct mailInfo
{
/// char*
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public byte[] mailFrom;
/// char*
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public byte[] mailReceivers;
/// char*
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public byte[] mailDate;
/// char*
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public byte[] mailTitle;
/// char*
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public byte[] mailBody;
}
[DllImport("my.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern List<mailInfo> rData(byte[] dbPath, byte[] TBFullName);
代码C#呼叫是;
Code C # call is;
List<loadDLL.mailInfo> ml = new List<loadDLL.mailInfo>();
byte[] bTN = Encoding.Default.GetBytes(TN);
byte[] bdbPath = Encoding.Default.GetBytes(Form1.datePath + emailFromAddress);
loadDLL.rData(bdbPath, bTN);
但是当我运行debug时,提示如下:
无法编组返回值:无法编组泛型类型。
我想知道如何从C ++返回列表数据,谢谢!
But when I run debug, the following tips:
Unable to marshal "return value": unable to marshal the generic type.
I wonder how to return list data from C ++, thank you!
推荐答案
这不会起作用,因为C ++运行时无法为C#运行时分配内存。所以你需要为C ++提供字符串缓冲区。
也许你可以使用带静态缓冲区的结构,如:
This wont work because, the C++ runtime cant allocate memory for the C# runtime. So you need to provide the string buffer for C++.
Maybe you can use a struct with static buffers like:
struct mailInfo
{
byte mailFrom[50];
//...
}
如果它不起作用,那就做一个格式化字符串并解析它C#。
伪代码:
If it doesnt work, than make a "formatted string" and parse it C#.
Pseudocode:
"mailfrom\nmailReceivers\n..."
//split in C#
String[] mailInfo = s.Split('\n');
除了解决方案1之外,您还可以使用C ++ / CLI在同一个程序集中创建桥接器或另外一个。
在这种情况下,您可以使用C ++ / CLI代码创建托管结构,如果您超出P / Invoke功能,则可以更轻松地进行任何所需的转换。
顺便说一下,双方的所有字符串都应该是ide ally是Unicode。
在字符串的C#端有字节[]根本没有任何意义。
In addition to solution 1, you can also use C++/CLI to make the bridge either in the same assembly or an additional one.
In that case, you can create the managed structure from C++/CLI code and it is then much easier to do any required conversion if you go outside of P/Invoke capabilities.
By the way, all strings in both side should ideally be Unicode.
Having byte[] on C# side for strings does not make any sense at all.
这篇关于C#调用C ++ dll返回列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文