P/Invoke 从 C# 到 C++ 的外部方法

Posted

技术标签:

【中文标题】P/Invoke 从 C# 到 C++ 的外部方法【英文标题】:P/Invoke external method from C# to C++ 【发布时间】:2016-10-29 12:47:00 【问题描述】:

我编写了以下 C++ 共享库:

#include "iostream"

#if defined(_WIN32) || defined(_WIN64)
    #define Q_DECL_EXPORT __declspec(dllexport)
    #define Q_DECL_IMPORT __declspec(dllimport)
#else
    #define Q_DECL_EXPORT
    #define Q_DECL_IMPORT
#endif

#ifdef MATINCHESS_LIBRARY
#  define MATINCHESS_API Q_DECL_EXPORT
#else
#  define MATINCHESS_API Q_DECL_IMPORT
#endif

using namespace std;

string* memory;

extern "C"

    MATINCHESS_API void Initialize();
    MATINCHESS_API void Uninitialize();
    MATINCHESS_API void Put(string text);
    MATINCHESS_API string Get();

    void Initialize()
    
        memory = new string;
    

    void Uninitialize()
    
        delete memory;
    

    void Put(string text)
    
        memory->assign(text);
    

    string Get()
    
        return *memory;
    

这是我的 C# 控制台应用程序:

using System;
using System.Runtime.InteropServices;

namespace MatinChess

    class MainClass
    
        const string MatinChessDLL = "libMatinChessDLL.so";

        [DllImport(MatinChessDLL)]
        public static extern void Initialize();
        [DllImport(MatinChessDLL)]
        public static extern void Uninitialize();

        [DllImport(MatinChessDLL)]
        public static extern void Put(string text);

        [DllImport(MatinChessDLL)]
        public static extern string Get();

        public static void Main (string[] args)
        
            Console.WriteLine ("Initializing...");
            Initialize ();
            Console.WriteLine ("Initialized");

            Console.WriteLine ("Write: ");
            Put (Console.ReadLine ());
            Console.WriteLine ("Value is put.");

            Console.WriteLine ("You wrote \"" + Get () + "\"");
            Console.ReadKey ();

            Console.WriteLine ("Uninitializing...");
            Uninitialize ();
            Console.WriteLine ("Uninitialized");
        
    

它安全地初始化并放入来自ReadLine 的字符串,但是当它想要调用Get 方法时,它会因长堆栈跟踪而崩溃。

请帮我找出问题。

【问题讨论】:

为什么不在 C++/CLR 代码中公开您的类接口,将其编译为单独的库并引用该库以在 C# 中使用? @edition 因为我在 Linux 中,我的编译器是 GCC。 【参考方案1】:

您不能将 std::string 从 C++ 编组到 C#。您必须使用字符缓冲区。看到这个问题:Passing strings from C# to C++ dll and back -- minimal example

【讨论】:

以上是关于P/Invoke 从 C# 到 C++ 的外部方法的主要内容,如果未能解决你的问题,请参考以下文章

在通过 P/Invoke 获得的 C++ 结构上设置 C# 回调

C#高阶与初心:P/Invoke平台调用

从 C++ 到 C# 的 P/Invoking int[] 显示随机大数而不是原始数组成员

在 C# 中为 p/invoke 创建一个基本的 C++ .dll

将非 Blittable 结构从 C# 编组到 C++

P/Invoke Struct with Pointers, C++ from C#