c# - 导出 c++ 函数并在 c# System.AccessViolationException 处使用函数

标签 c# c++ dll dllimport dllexport

您好,我尝试从 C++ 导出函数并尝试在 C# 上运行它,但我收到一个错误,提示 System.AccessViolationException:尝试读取或写入 protected 内存。这通常表明另一个内存已损坏。,我这样做要感谢微软的例子,但我得到了这个错误,我找不到任何关于这个的信息。我在任何地方都错了吗?

C++头文件

#ifndef KKKKK_V2_EXPORTS
#define KKKKK_V2_API __declspec(dllexport)
#else
#define KKKKK_V2_API __declspec(dllimport)
#endif

extern "C" KKKKK_V2_API can* create_can(string ip, int port);

extern "C" KKKKK_V2_API int connectCan(can* _c);


extern "C" KKKKK_V2_API string browseCan(can* _c,int x);

extern "C" KKKKK_V2_API void dataset_browseCan(can* _c);

extern "C" KKKKK_V2_API void dataset_signals_readingCan(can* _c);

extern "C" KKKKK_V2_API void GI_Can(can* _c);

extern "C" KKKKK_V2_API void ConcludeCan(can* _c);

Cpp文件

can* create_can(string ip, int port) {
    const char* my_ip=ip.c_str();
    can* _c = new can();
    _c->connection = new connect_tcp((char*)my_ip, port);
    _c->s = _c->connection->ConnectWithTcp();
    _c->list = new LinkedList * [1000];
    return _c;
}
int connectCan(can* _c) {
    cotp_connection(_c->cotp, _c->connection, _c->response, _c->list, _c->s);
    return 1;
}
string browseCan(can* _c,int x) {
    int i = 0;
    initiate_request(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s);
    confirmed_request(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s);
    continue_confirmed_request_with_more_follows(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s);
    all_object_browse(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s);
    auto it = _c->response.object_list.begin();
    while (i < x) {
        it++;
        i++;
    }
    return *it; 
}
void dataset_browseCan(can* _c) {
    dataset_browse(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s);
    dataset_signals_browse(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s); 
    _c->signals = new Signals[_c->response.real_signals_and_values.size()];
}
void dataset_signals_readingCan(can* _c) {
    dataset_signals_reading(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s, _c->signals);
}
void GI_Can(can* _c) {
    write_data_pins(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s, _c->signals);
    general_information(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s, _c->signals);
}
void ConcludeCan(can* _c) {
    conclude(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s, _c->signals);
    release(_c->cotp, _c->mms_obj, _c->connection, _c->response, _c->list, _c->size_encoder, _c->s, _c->signals);
}

C#文件

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace cppDllTest
{
    class Program
    {

        [DllImport(@"C:\Users\serhan.erkovan\source\repos\kkkkk_v2\Debug\kkkkk_v2.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern IntPtr create_can(string my_ip_address, int my_port);
        IntPtr _c;
        _c = create_can("10.6.35.225", 102);   //ERROR IS HERE
    }
}

我放了我的 cpp 文件,但我知道这不是必需的。也许我放错了 cpp 文件,因为我放了那个。

在 Dependency Walker 中,我所有导出的函数在“E”部分都是灰色的。意思是“驻留在所选模块中的 C 导出函数。”

最佳答案

这里的问题是,如这里所述https://stackoverflow.com/a/20752021/3852949 :

You cannot pass a C++ std::string across an interop boundary. You cannot create one of those in your C# code

您可以更改 C++ 函数签名,使其接受 const char *(即 can* create_can(const char * ip, int port))或创建调用原始函数的适配器函数:

can* create_can_adapter(const char * ip, int port)
{
    std::string s(ip);

    return (create_can(s, port));
}

关于c# - 导出 c++ 函数并在 c# System.AccessViolationException 处使用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59410346/

相关文章:

python - Cx_Freeze DLL 加载失败

c# - 在 C# 应用程序性能中访问 C++ 代码

c# - 动态 Windows 窗体控件创建 - 一般问题

c# - 在 EF4 和 SQL Compact 4 中使用 TransactionScope 时出错

c# - WebRequest GetResponseStream 读取字节

c++ - 模板模板参数的 "Transparency"(缺少模板参数)

c# - 在 C# 中,如何创建附加到变量的方法?

c++ - 使用模板返回一个通用的 C 风格数组

c++ - 模板继承 - 分配失败

c# - 如何将用户设计的窗体编译添加到工程中