0

Hello i tried to export functions from c++ and tried to run it at c# but i got an error that System.AccessViolationException: An attempt to read or write protected memory. This is usually an indication that the other memory is corrupted., I did this thanks to microsoft example but i got this error and i cannot find anything about this. Am i wrong at any places ?

C++ header file

#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 file

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# file

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
    }
}

I put my cpp file but it is not necessary, i know.Maybe i am wrong at cpp file because of this ı put that.

At Dependency Walker my all functions that export seems grey at 'E' section.That's meaning is " C export function that resides in the selected module."

7
  • Which platform did you pick in "Platform for Build"? Maybe this top answer could help : stackoverflow.com/a/18252141/3852949 Commented Dec 19, 2019 at 13:18
  • @Storm Visual Studio 2019 (v142) i build for x64 and x86 but got this error every time Commented Dec 19, 2019 at 13:21
  • Have you tried compiling your c++ code and checked if the compiled binary works as expected before interfacing it with P/Invoke? As a sidenote I'd like to point that _c->connection = new connect_tcp((char*)my_ip, port); will result in a dangling pointer as the pointer returned by ip.c_str() won't be valid anymore when you leave the scope since it's based on a temporary variable. Commented Dec 19, 2019 at 13:36
  • It is working on c++ ,i tried it wit no errors. Commented Dec 19, 2019 at 13:46
  • 1
    Try changing can* create_can(string ip, int port) prototype to can* create_can(const char * ip, int port) and change the c++ code accordingly. The type string in C# doesn't equate to std::string in C++. Commented Dec 19, 2019 at 13:53

1 Answer 1

1

The issue here is that, as explained here 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

You could either change the C++ function signature so that it accepts a const char * (i.e can* create_can(const char * ip, int port)) or create an adapter function calling your original function :

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

    return (create_can(s, port));
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.