从c+返回字符串+;从c调用的dll导出函数# 我试图从一个C++ DLL导出函数返回一个字符串。我从c#调用此函数。我在网上看到了很多例子,我真的很困惑该怎么办 我的C++代码导出函数: extern "C" __declspec(dllexport) char* __cdecl getDataFromTable(char* tableName) { std::string st = getDataTableWise(statementObject, columnIndex); printf(st.c_str()); char *cstr = new char[st.length() + 1]; strcpy(cstr, st.c_str()); return cstr; } _declspec(dllexport) BSTR getDataFromTable(const char* tableName) { return SysAllocString(L"String to return"); }

从c+返回字符串+;从c调用的dll导出函数# 我试图从一个C++ DLL导出函数返回一个字符串。我从c#调用此函数。我在网上看到了很多例子,我真的很困惑该怎么办 我的C++代码导出函数: extern "C" __declspec(dllexport) char* __cdecl getDataFromTable(char* tableName) { std::string st = getDataTableWise(statementObject, columnIndex); printf(st.c_str()); char *cstr = new char[st.length() + 1]; strcpy(cstr, st.c_str()); return cstr; } _declspec(dllexport) BSTR getDataFromTable(const char* tableName) { return SysAllocString(L"String to return"); },c#,c++,windows-ce,C#,C++,Windows Ce,当我试图从c#调用此函数时: 我打电话时出错了。我正在为WinCE 6.0创建这个 编辑------------------------ 有一种类似的方法,我可以把一个空的缓冲区从C++传递给C++,C++函数将填充数据,我可以在C<< /p> < p>中重用它。最近我也遇到了这个问题,尽管我有一个解决方案,但我真的不能解释它。我还没有找到一个合理的解释 我的C++字符串检索代码是: extern "C" { __declspec(dllexport) void __GetValue__(cha

当我试图从c#调用此函数时:

我打电话时出错了。我正在为WinCE 6.0创建这个

编辑------------------------


有一种类似的方法,我可以把一个空的缓冲区从C++传递给C++,C++函数将填充数据,我可以在C<< /p> < p>中重用它。最近我也遇到了这个问题,尽管我有一个解决方案,但我真的不能解释它。我还没有找到一个合理的解释

我的C++字符串检索代码是:

extern "C" { __declspec(dllexport) void __GetValue__(char* str, int strlen); }
和我的C#代码:

这样,您可以返回一个字符串,而不是返回一个值(使用String Bu建器),让C++填充数据:

void __GetValue__(char* str, int strlen) {
    std::string result = "Result";

    result = result.substr(0, strlen);

    std::copy(result.begin(), result.end(), str);
    str[std::min(strlen-1, (int)result.size())] = 0;
}
为确保完整性,请求字符串的C#代码:

public String GetValue() {
    StringBuilder str = new StringBuilder(STRING_MAX_LENGTH);

    __GetValue__(str, STRING_MAX_LENGTH);

    return str.ToString();
}

NET运行时使用unicode(wchar\t)字符串,而不是ascii(char),因此需要进行一些更改。 您还应该考虑.NET无法释放由C/C++应用程序分配的字符串,因此,预先分配并从C中传递的缓冲区是唯一安全的方法来管理,而不会导致内存泄漏或更坏。

< P>(注意,它假定长度正确-您应该传入缓冲区长度并防止溢出等):

然后在C#中:


注意,这确实对C++应用程序中的字符编码不是Unicode做出了一些假设。如果它们是Unicode,则使用UTF16代替ASCII。< /P> < P>在Windows上,可以直接使用<代码> BSTR 返回字符串(从 WType。H< /代码>由<代码> Windows > H <代码> >.

BSTR
可以通过
SysAllocString
函数从标准宽字符串创建:

extern "C" __declspec(dllexport)  char*  __cdecl getDataFromTable(char* tableName)
{
    std::string st = getDataTableWise(statementObject, columnIndex);
    printf(st.c_str()); 

    char *cstr = new char[st.length() + 1];
    strcpy(cstr, st.c_str());
    return cstr;
} 
_declspec(dllexport) BSTR getDataFromTable(const char* tableName)
{
    return SysAllocString(L"String to return");
}
然后在C#中,将返回类型封送为
BStr

[DllImport("\\SD Card\\ISAPI1.dll", CallingConvention = CallingConvention.Cdecl )]
[return: MarshalAs(UnmanagedType.BStr)]
static extern string getDataFromTable(string tableName);

控制台出现OutOfMemory异常。writeLine(字符串值)当然,没有人会调用delete[]来再次释放字符串缓冲区空间。这最终会以OOM结束。您不能这样做。请先尝试CoTaskMemAlloc()。然后允许调用方提供缓冲区,如int getDataFromTable(char*tableName,char*buffer,int buflen)。必须是C端的StringBuilder,具有足够的容量。不应该
私有静态外部字符串getDataFromTable
be
私有静态外部无效getDataFromTable
?Marshallas(UnmanagedType.BStr)适合我。谢谢
_declspec(dllexport) BSTR getDataFromTable(const char* tableName)
{
    return SysAllocString(L"String to return");
}
[DllImport("\\SD Card\\ISAPI1.dll", CallingConvention = CallingConvention.Cdecl )]
[return: MarshalAs(UnmanagedType.BStr)]
static extern string getDataFromTable(string tableName);