从c#调用的c++ dll导出函数返回字符串
Return string from c++ dll export function called from c#
我试图从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;
}
当我尝试从c#中调用这个函数时:
[DllImport("\SD Card\ISAPI1.dll")]
private static extern string getDataFromTable(byte[] tablename);
static void Main(string[] args)
{
string str = getDataFromTable(byteArray);
Console.writeLine(str);
}
调用时出现错误。我正在为WinCE 6.0创建这个
编辑 ------------------------
是否有类似的东西,我可以从c#传递一个空缓冲区给c++, c++函数将填充数据,我可以在c#中重用它
我最近也遇到过这个问题,虽然我有一个解决方案,但遗憾的是我不能真正解释它。我还没有找到一个合理的解释。
我的c++代码检索字符串是:
extern "C" { __declspec(dllexport) void __GetValue__(char* str, int strlen); }
和我的c#代码:
[DllImport("MyDLL.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void __GetValue__(StringBuilder str, int strlen);
因此,正如您所看到的,您可以提供一个字符串(通过使用StringBuilder),而不是返回一个值,并让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();
}
这样如何(注意,它假设正确的长度-您应该传入缓冲区长度并防止溢出等):
extern "C" __declspec(dllexport) void __cdecl getDataFromTable(char* tableName, char* buf)
{
std::string st = getDataTableWise(statementObject, columnIndex);
printf(st.c_str());
strcpy(buf, st.c_str());
}
然后在c#中:
[DllImport("\SD Card\ISAPI1.dll")]
private static extern string getDataFromTable(byte[] tablename, byte[] buf);
static void Main(string[] args)
{
byte[] buf = new byte[300];
getDataFromTable(byteArray, buf);
Console.writeLine(System.Text.Encoding.ASCII.GetString(buf));
}
注意,这确实对你的c++应用程序中的字符编码不是unicode做了一些假设。如果是unicode,请使用UTF16而不是ASCII。
在windows上,您可以直接使用BSTR
返回字符串(从wtypes.h
包含到windows.h
)。SysAllocString
函数可以从标准宽字符串创建BSTR
:
_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);
. net运行时使用unicode (wchar_t)字符串,而不是ascii (char),所以这需要一些更改。你还应该考虑到。net没有办法释放由C/c++应用程序分配的字符串,所以让缓冲区预分配并从c#传入是唯一安全的方法来管理它,而不会导致内存泄漏或更糟。
这很简单:)
_strdup
在内存中创建字符串的副本,该副本只能使用delete
销毁。
https://learn.microsoft.com/en us/cpp/c -运行- library/reference/strdup wcsdup - mbsdup?view=msvc - 170
const char* returnStringFunc()
{
return _strdup("String to Return");
}
- 从函数返回const char*数组
- 检查函数返回类型是否与STL容器类型值相同
- 从 c 或 cpp 系列子函数返回到主函数
- 从函数返回任意简单类型的数据
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 从 C++ 中的函数返回数组地址问题
- VirtDisk.h QueryChangesVirtualDisk() 函数返回 RangeCount 为 0
- 为什么glGetSubroutineIndex为不同的函数返回相同的值?
- 在 c++ 中将函数返回类型指定为模板参数
- 从封装在对象中的函数 C++ 返回时为空的列表
- 为什么向量内部的指针在从函数返回时会发生变化?
- 函数返回的 rvalue 引用(表达式)是 xvalue - 但没有标识?
- 程序中的布尔函数返回输入的范围无论如何都是无效的
- 寿命延长从函数返回引用
- 程序不向函数返回值
- 字符串函数返回奇怪的值
- 类的大问题,以及从空函数c++返回
- 为什么在尝试测量函数返回所需的时间时,我的运行时编号是错误的?
- C++二叉搜索树模板从函数返回节点
- NVCC 错误:string_view.h:constexpr 函数返回是非常量