警告 C4190 C-linkage-specified

Posted

技术标签:

【中文标题】警告 C4190 C-linkage-specified【英文标题】:Warning 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”,您会发现一些有关如何执行此操作的建议。 欢迎来到 ***.. :) 【参考方案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 构造函数/析构函数。

【讨论】:

以上是关于警告 C4190 C-linkage-specified的主要内容,如果未能解决你的问题,请参考以下文章

警告执行已完成,带有警告存储过程

怎么忽略KEIL的警告

IOS警告消除

Quick.db unwarn 命令取消警告成员中的所有警告

java程序中很多警告,如何修改掉?

将特定级别的所有警告视为错误,而不是下一级的警告