【问题标题】:Warning C4190 C-linkage-specified警告 C4190 C-linkage-specified
【发布时间】:2013-12-27 09:27:55
【问题描述】:

目前我正在使用 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 使用 STL 类型。
  • 我不认为 std::string 和 C# 字符串混合得很好。 (如果可能的话,我愿意接受这方面的教育。)。相反,只需 export 导出一个使用 char* 作为参数的 C 函数。在网络上搜索“P/Invoke”,您会发现一些有关如何执行此操作的建议。
  • 欢迎来到 StackOverFlow.. :)

标签: c++ c dll


【解决方案1】:

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

C#部分:您可以查看 MSDN Platform Invoke Data Types 进行转换。

【讨论】:

    【解决方案2】:

    两种方式:

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

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

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

    Second 适用于任何语言:

    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# 中使用,您需要一个使用 StringBuilder 的 p/invoke 声明,用于表示输出字符串的参数。

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

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

    【讨论】:

      猜你喜欢
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多