【问题标题】:string passed from C++ to C# prints blank从 C++ 传递到 C# 的字符串打印空白
【发布时间】:2016-12-05 20:24:30
【问题描述】:
#ifdef SERVER_TCP_EXPORTS
class __declspec(dllexport) Sock_Server
#else
class __declspec(dllimport) Sock_Server
#endif
{
public:
    int Server(const char* strErr,int bufSize);
    ...
 }

cpp file
int Sock_Server::Server(const char* strErr,int bufSize)
{
   // do something and assign the string to strErr
   (say) strErr = "Hello World";
   return -1;
}

in C#
[DllImport("Hello.dll", EntryPoint = "Server" CallingConvention = CallingConvention.StdCall)]

private extern static int Server(StringBuilder strErr, int bufSize);

public static int Connect(StringBuilder strErr, int bufSize)
{
   int res = Server(strErr,bufSize);    /// when the calls come here, strErr is empty
    return res;          // res has the value  -1
}

private void Form1_Load(object sender, EventArgs e)
{
   int res = 0;
   int bufSize = 4096;
   StringBuilder strErr = new StringBuilder(bufSize+1);

   res = Connect(strErr, bufSize); //when the calls come here, strErr is empty
    MessageBox.Show(strErr.ToString());   // it has the value -1
}

我不是 C# 人。我在发布之前做了一些阅读,并尝试了所有可能的组合,但由于某种原因它不起作用。我使用的是 Visual Studio 2013。我有几个 Q

[Q1] 当我做 MessageBox.Show(strErr.ToString());在我的 C# 中,它只打印一个空白字符串!如果有人可以帮助我,我将不胜感激,因为我对这一切都很陌生。

[Q2] 如果我给 EntryPoint ="Server" 我的代码不起作用。它抱怨,在 Hello.dll 中找不到服务器的入口点。所以,每次我必须使用 dumpbin.exe 在我的 dll 中找到确切的条目,然后准确地提供编译器为我创建的方式

[DllImport("Hello.dll", EntryPoint = "?Server@Sock_Server@@QAEHPBDH@Z" CallingConvention = CallingConvention.StdCall)]

有没有更好的方法来做到这一点。这使代码陷入困境

[Q3] 有没有办法调用 C++ 构造函数/析构函数。我确实需要调用它们。我通过其他方法调用了 C'tor,我知道这不是一个好主意。任何帮助将不胜感激.

谢谢。

【问题讨论】:

  • 不要在 C++ 中分配字符串,(你只是在这里覆盖了提供的指针,任何调用函数都看不到)。将其复制到提供的strErr缓冲区,而不是使用strcpy_s之类的东西。
  • 要么你在某处丢失了static,要么你真的试图将实例方法调用为静态方法,这是非常错误的,因为你会丢失this。除非您在命令行上覆盖它,否则调用约定不是stdcall,而是“C++ 特定调用”。而且 C# 在内部使用 UTF-16,所以 char* 也不起作用。而且你不能从 C# 实例化 C++ 对象,所以不用担心析构函数......这里有很多错误我不知道从哪里开始。我的建议是从一个小的工作样本重新开始。
  • 它是一个C++类的实例函数。实例函数有一个额外的隐藏 this 参数。您的代码不会崩溃是因为您也没有编写有效的 C++ 代码,必须使用 strcpy_s() 复制字符串。你不能调用这样的函数,你没有很好的方法来为 this 创建正确的值。您必须将函数设为 static 或使用 C++/CLI 项目为类编写包装器。

标签: c# c++ c++11 visual-c++


【解决方案1】:

我不认为这都与静态有关。这都是关于正确分配对象的。当从其他 C++ 调用时,同一段代码工作得非常好。我稍微调整了代码。现在,我使用 strcpy_s 并且它正在工作,因为在整理数据时,我丢失了数据。

我还在等待 Q2 的回答。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 2012-09-04
    • 2015-12-23
    • 2014-02-24
    • 2011-03-02
    • 1970-01-01
    相关资源
    最近更新 更多