Importing c++ dll in c# project

天涯浪子 提交于 2019-12-10 16:06:58

问题


I am importing some c++ dll into a c# project, I am using visual studio 2010. I have succeded to import function that are using built-in type, however I am getting error when I have tried to deal with structure. This is a simple example:

c++ code

typedef long int TDate;

typedef struct _TMDYDate
{
    long month;                         /* In range [1,12] */
    long day;                           /* In range [1-31] */
    long year;                          /* In range [1600-] */
} TMonthDayYear;

int JpmcdsDateToMDY
    (TDate date,                        /* (I) TDate format */
     TMonthDayYear *mdyDate);

and I have translated to c# as:

   [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct TMonthDayYear {
    public int month;
    public int day;
    public int year;
}

public partial class NativeMethods {

    [System.Runtime.InteropServices.DllImportAttribute("MyDll.dll", EntryPoint="JpmcdsDateToMDY")]
public static extern  int JpmcdsDateToMDY(int date, ref TMonthDayYear mdyDate) ;

}

when I try to run the function in my test program I get this error:

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at CsharpWrapper.NativeMethods.JpmcdsDateToMDY(Int32 date, TMonthDayYear& mdy Date)

The struct are declare in the stack and I thought (maybe) was the problem but I am still getting the same error even though I have change TMonthDayYear to class.

What am I doing wrong?

Thanks for you help.


回答1:


You have to use the CallingConvention property in the [DllImport] attribute, this is Cdecl since you didn't use __stdcall in the native function declaration. While that's wrong, it is not a great explanation for the AV. You need to debug the C code, the AV suggests it has a pointer bug. Project + Properties, Debug, tick "Enable unmanaged code debugging" and set a breakpoint on the C function.

Frankly, a date conversion like this should be written in pure C#.




回答2:


TDate type in native code is long int but in managed code it represented as int32 instead int64.




回答3:


It may or may not be related, but you need the [OutAttribute] on the mdyDate parameter in order to write to it.




回答4:


If you are an accustomed user in c++ you are probably familiar with pointers addressing the memory directly. Your error looks like a memory read/write protection related problem.

This is prohibited by standard nature of C# and u have to put the compiler in Unsafe mode.

If you code unsafe in c# u have to put code into unsafe mode.

   unsafe
   {
     // unsafe things
   }

   unsafe class Class1 {}

   static unsafe void someMethod ( int* cpi, int lngth) {...} 

You also have to check the project configuration (Build-tab) and tack the checkbox for "Allow unsafe code".

I apologize if I was scrolling by some too obvious information. I will also state that this comment only has meaning if the situation is that C# going to address memory.



来源:https://stackoverflow.com/questions/5193243/importing-c-dll-in-c-sharp-project

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!