在 c# System.AccessViolationException 导出 c++ 函数和使用函数
Exporting c++ functions and use functions at c# System.AccessViolationException
你好,我尝试从 C++ 导出函数并尝试在 C# 中 运行 它,但我得到一个错误 System.AccessViolationException: An attempt to read or write protected memory. This is usually an indication that the other memory is corrupted.
,我这样做感谢微软的例子,但我得到了这个错误,我找不到关于此的任何信息。我在任何地方都错了吗?
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 文件,但这不是必需的,我 know.Maybe 我放错了 cpp 文件,因为这个我放了那个。
在 Dependency Walker 中,我所有导出的函数在 'E' 处显示为灰色 section.That 的意思是“驻留在所选模块中的 C 导出函数。”
这里的问题是,正如这里所解释的那样 :
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# 中 运行 它,但我得到一个错误 System.AccessViolationException: An attempt to read or write protected memory. This is usually an indication that the other memory is corrupted.
,我这样做感谢微软的例子,但我得到了这个错误,我找不到关于此的任何信息。我在任何地方都错了吗?
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 文件,但这不是必需的,我 know.Maybe 我放错了 cpp 文件,因为这个我放了那个。
在 Dependency Walker 中,我所有导出的函数在 'E' 处显示为灰色 section.That 的意思是“驻留在所选模块中的 C 导出函数。”
这里的问题是,正如这里所解释的那样 :
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));
}