C#调用C ++ dll返回列表 [英] C # to call C ++ dll return list

查看:77
本文介绍了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(&quot;my.dll&quot;, CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern List&lt;mailInfo&gt; 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆