简体   繁体   English

如何从C#中的非托管C ++ DLL正确调用方法?

[英]How to correctly call methods from unmanaged C++ DLL in C#?

I have an acquisition board controlled with a C++ API. 我有一个用C ++ API控制的采集板。 I want to call the methods directly from my C# application. 我想直接从我的C#应用​​程序中调用方法。

These are the methods which cause problems: 这些是导致问题的方法:

DLL: DLL:

// Read the DATA of the board
SPINAPI int pb_get_data(unsigned int num_points, int *real_data, int *imag_data);
// Write plain ASCII file for the data returned from pb_get_data(..)
SPINAPI int pb_write_ascii(const char *fname, int num_points, float SW, float SF, const int *real_data, const int *imag_data);

where SPINAPI is defined as follows: 其中SPINAPI定义如下:

#ifdef __WINDOWS__
#ifdef DLL_EXPORTS 
#define SPINAPI __declspec(dllexport)
#else
#define SPINAPI __declspec(dllimport)
#endif
#else
#define SPINAPI
#endif

C#: C#:

[DllImport(@"C:\SpinCore\SpinAPI\lib32\spinapi.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int pb_get_data(uint num_points, [MarshalAs(UnmanagedType.LPArray)] ref int[] real_data, [MarshalAs(UnmanagedType.LPArray)] ref int[] imag_data);

[DllImport(@"C:\SpinCore\SpinAPI\lib32\spinapi.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int pb_write_ascii(string fname, int num_points, float SW, [MarshalAs(UnmanagedType.LPArray)] ref int[] real_data, [MarshalAs(UnmanagedType.LPArray)] ref int[] imag_data);

When calling pb_get_data() , 调用 pb_get_data()

pb_get_data((uint)numberOfPoints, ref idata, ref idata_imag);

I get the following error : 我收到以下错误

System.AccessViolationException was unhandled

Message: An unhandled exception of type 'System.AccessViolationException' occurred in Unknown Module.
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

When calling pb_write_ascii() , 调用 pb_write_ascii()

pb_write_ascii(@"data\direct_data_0.txt", numberOfPoints, (float)actualSW, ref idata, ref idata_imag);

where: 哪里:

int[] idata = new int[MAX_NUMBER_POINTS];
int[] idata_imag = new int[MAX_NUMBER_POINTS];

nothing happens (the file is not written). 没有任何反应 (未写入文件)。

Does anybody have an idea about what I'm doing wrong and how to correct the problems? 有人对我在做什么错以及如何纠正问题有想法吗? I mention that I could successfully call other methods from the DLL. 我提到我可以从DLL成功调用其他方法。

According to Hans Passant, eliminating the ref keyword was causing the problem. 根据Hans Passant的说法,消除ref关键字是造成此问题的原因。 Removing it resolved the issue. 删除它可以解决问题。

Usage of C++/Cli wrapped library can be possible solution. 可以使用C ++ / Cli包装的库。 You should create C++/Cli library, which will contain such code: 您应该创建C ++ / Cli库,其中将包含以下代码:

namespace ManagedCode {

    public ref class WrappedFunctions
    {
    public: 
        static int pb_get_data(unsigned int num_points, array<int>^ real_data, array<int>^ imag_data)
        {
            pin_ptr<int> temp_real_data = &real_data[0];
            pin_ptr<int> temp_imag_data = &imag_data[0];
            return UnManagedCode::pb_get_data(num_points, temp_real_data, temp_imag_data);
        }
    };
}

In other cases, you can use marshalling functions 在其他情况下,可以使用编组功能

For detailed information, read https://msdn.microsoft.com/ru-ru/library/1dz8byfh.aspx 有关详细信息,请阅读https://msdn.microsoft.com/ru-ru/library/1dz8byfh.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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