Click here to Skip to main content
15,893,381 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to be a C ++ DLL for C # call and return list, type is a structure defined
c ++ The structure is;
C#
struct mailInfo
{
    const char *mailFrom;
    const char *mailReceivers;
    const char *mailDate;
    const char *mailTitle;
    const char *mailBody;
}

;
C ++ code is:

C++
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;  
}

The structure is defined in C #:
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);


Code C # call is;
C#
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);


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!
Posted
Updated 15-Aug-15 19:33pm
v3
Comments
George Jonsson 16-Aug-15 1:36am    
You could try to return a regular pointer to an array instead of a list.
Or try a CComSafeArray.

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:
C++
struct mailInfo
{
    byte mailFrom[50];
    //...
}


If it doesnt work, than make a "formatted string" and parse it C#.

Pseudocode:
C++
"mailfrom\nmailReceivers\n..."
//split in C#
String[] mailInfo = s.Split('\n');
 
Share this answer
 
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.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900