警告 C4190 C 联动指定

Warning C4190 C-linkage-specified

本文关键字:C4190 警告      更新时间:2023-10-16

目前我正在使用C++制作一个dll函数。之后,我使用 DllImport 将此 dll 导入我的 C# 项目。在我的C++项目中,我在第一次构建过程中收到了警告 C4190。

警告 C4190:"abc"指定了 C 链接,但返回UDT'std::basic_string' 与 C 不兼容

我当前的代码如下:

extern "C"
{
  __declspec(dllexport) std::string abc(std::string targetFile)
  { 
    return somestring;
  }
}

C++ 部分:您不能extern “C"界面中使用命名空间和C++对象。尝试使用更原始的类型,如intfloatchar和指针(例如 char * ) 在返回值和参数中。

C# 部分:您可以检查 MSDN 平台调用数据类型以进行转换。

两种方式:

首先需要具有/clr选项的 Visual C++ 编译器:

public ref struct CppLib
{
  static System::String^ abc(System::String^ targetFile)
  { 
    return gcnew System::String(somestring);
  }
}

C# 将其视为用 C# 编写的函数。

第二个是任何语言都可以做到的:

extern "C"
{
  __declspec(dllexport) size_t abc(const char* szTargetFile, char* szResult, size_t nResultBytes)
  { 
    std::string targetFile(szTargetFile);
    strncpy(szResult, somestring, nResultBytes);
    return strlen(somestring);
  }
}

若要从 C# 使用,需要一个 p/invoke 声明,使用 StringBuilder 表示输出字符串的参数。

第三种方法是使用BSTRSysAllocStringSysFreeString API函数)。 C++中有一个bstr_t包装器。 在 C# 中设置了一个属性,让 p/invoke 知道字符串是一个BSTR

重要的是双方就字符串的分配和解除分配方式达成一致。 这意味着永远不要使用特定于C++实现的分配函数,如std::string构造函数/析构函数。