c# - 在 C# 中编码简单字符串

标签 c# c++ .net-4.0 pinvoke

我完全失败了这个非常简单的 P/Invoke。

    [System.Runtime.InteropServices.DllImport(
        "temp.dll"
    )]
    private static extern System.IntPtr parser_alloc();

    [System.Runtime.InteropServices.DllImport(
        "temp.dll", 
        CharSet = System.Runtime.InteropServices.CharSet.Ansi
    )]
    private static extern void parser_add_file(
        System.IntPtr p,
        [MarshalAs(UnmanagedType.LPStr)]string f,
        [MarshalAs(UnmanagedType.LPStr)]string s);

    [System.Runtime.InteropServices.DllImport(
        "temp.dll"
    )]
    private static extern void parser_free(
        System.IntPtr p);

    [System.Runtime.InteropServices.DllImport(
        "temp.dll"
    )]
    private static extern void parser_emit_results(
        System.IntPtr p);

    [System.Runtime.InteropServices.DllImport(
        "temp.dll",
        CharSet = System.Runtime.InteropServices.CharSet.Ansi
    )]
    private static extern void parser_file_updated(
        System.IntPtr p,
        [MarshalAs(UnmanagedType.LPStr)]string f,
        int offset,
        int added);

创建对象似乎很顺利。但是,当我尝试调用 parser_add_file 时,运行时告诉我签名不匹配。这是我现有的 C++ 代码:

class Parser {
public:
    void add_file(std::string filename, std::string source) {
        std::cout << "add_file | " << filename << " | " << source << "\n";
    }
    void clear_contents() {
        std::cout << "clear_contents\n";
    }
    void emit_results() {
        std::cout << "emit_results\n";
    }
    void file_updated(std::string filename, int offset, int added) {
        std::cout << "file_updated | " << filename << " | " << offset << " | " << added << "\n";
        // added should be negative to signify removing
    }
    Parser() {
        std::cout << "I made a Parser!\n";
    }
};

extern "C" __declspec(dllexport) Parser* parser_alloc() {
    return new Parser;
};

extern "C" __declspec(dllexport) void parser_add_file(Parser* p, const char* filename, const char* string) {
    p->add_file(filename, string);
}

extern "C" __declspec(dllexport) void parser_free(Parser* p) {
    delete p;
}

 extern "C" __declspec(dllexport) void parser_emit_results(Parser* p) {
    p->emit_results();
}

 extern "C" __declspec(dllexport) void parser_file_updated(Parser* p, const char* filename, int offset, int added) {
    p->file_updated(filename, offset, added);
}

我是否应该跳过 P/Invoke 并转到 C++/CLI 来完成这项工作?

最佳答案

事实证明,我必须手动将调用约定设置为 cdecl——默认为 stdcall。

关于c# - 在 C# 中编码简单字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4251306/

相关文章:

c# - 尽管有查询字符串,但在使用 sql COUNT 时 ExecuteNonQuery 返回 -1

c# - 从 Controller MVC 4 访问 UserProfile

javascript - 如何发送TCP保持事件数据包

c++ - 抑制单行的弃用警告

c# - 我应该为 ASP.NET MVC 应用程序中常用引用的程序集设置 copy local false 吗?

c# - .net activex 在框架 4.0 中不工作

c# - 无法将类型 'Newtonsoft.Json.Linq.JObject' 转换为复杂类型

c++ - 如何通知模型/ View 底层数据改变了表头?

c++ - 使用函数 fread() 读取文件中的数据 block

wcf - 在 WCF-netTCPBinding 中测试 TLS 安全性