简体   繁体   中英

getting an access violation error is c# while calling the c++ code

in c++ i have these below classes

class A
{
  public: 
      int __thiscall check(char *x,char *y,char *z);
  private:
      B *temp;
};

class B
{
  friend class A;
  Public:
    B();
    B(string x,string y,string z);
    ~B();
  private:
    string x;
    string y;
    string z;
};

my dll method in c++ is like this

__declspec(dllexport) int __thiscall A::check(char *x,char *y,char *z)
{
  temp=new B(x,y,z);
  return 1;
}

code for B() constructor is below:

B::B(string x, string y,string z)
{
  .......
}

below mentioned is my c# dll import

[DllImport("sour.dll", CallingConvention = CallingConvention.ThisCall, ExactSpelling = true, EntryPoint = "check")]
    public static extern void check(IntPtr val,string x,string y,string z);

the c++ build went successful with out any errors, but when i call this method from c# using dll import method i am getting this below error when i am trying to assign memory for "temp" class pointer. Below mentioned is the error.

 Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Can any one please help on this. Thanks in advance.

I would assume exporting methods instead of class members is easier. Please make sure that the DllImport uses the correct calling convention.

__declspec(dllexport) void __cdecl check(int x)

Using PInvoke Interop Assistant results in

public partial class NativeMethods {

    /// Return Type: void
    ///x: int
    [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="check", CallingConvention=System.Runtime.InteropServices.CallingConvention.Cdecl)]
public static extern  void check(int x) ;

}

Did you make sure that 32/64 bit version of your dll matches. If you run the x86 .net version (32bit) you can activate debugging of native and managed code and you should be able to set a break point in your C++ method to see what happens.

Using C++ directly via PInvoke will not work. A C++ class must first be instantiated via new on the heap which you cannot do from managaed code.

The member function you want to call needs to use in the DllImport statement the thiscall calling convention because it is a non static member method. This requires to implicitely pass the pointer to unmanaged class instance on the stack which you cannot really do here.

You should consider a managed C++ wrapper class (see link) to get direct access to it or you make a C wrapper where you can call ctor, dtor and instance members as direct C methods which accept and return the this pointer where necessary.

A very hacky solution might be to allocate the memory via Marshal.GlobalAlloc directly and call the ctor on this storage location via PInvoke but since you do not now in advance how much memory you need this is a dirty hack.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM