在C#中使用C dll中定义的typedef函数

时间:2013-06-05 02:27:55

标签: c# c++

我有一个project.dll和头文件。它定义如下:

#ifdef PPSDK_EXPORTS
#define PP_SDK_API __declspec(dllexport)
#else
#define PP_SDK_API __declspec(dllimport)
#endif
#ifndef __PP_SDK__
#define __PP_SDK__

typedef enum
{
    PP_FALSE= 0x0,
    PP_TRUE = 0x01
} pp_bool;

PP_SDK_API pp_bool SDK_Initialize(unsigned long*p_Status );

我在谷歌和网络上使用一些帮助在C#中使用这个dll,但它没有成功。 这是pp_bool类型的错误。 这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        [DllImport("project.dll")]
        static extern  pp_bool  SDK_Initialize(unsigned long*p_Status );
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

...................................... 你能帮我解决一下吗? 谢谢!

1 个答案:

答案 0 :(得分:0)

您的P / Invoke定义不起作用,因为C#中不存在pp_bool类型。问题是enum的大小由编译器在C ++中确定,因此我们无法确定大小是多少。它可能是byte上的shortint。虽然它是在Visual C ++中编译为C代码it looks like it would be an int。我的建议是尝试其中的每一个并确定哪些有效。

您还可以尝试将返回值声明为bool,这将是自然的.NET类型。但是通过default that assumes,返回值是32位(int size)。

在Windows上的C ++中,P / Invoke定义中存在另一个错误,long是32位值,而在.NET中,long是64位。因此,p_Status应该是uint,而不是unsigned long

此外,如果SDK_Initialize函数仅返回单个unsigned long值,则不需要使用指针。请改用ref参数。编组将负责转换,您不必使用不安全的代码。

最后,您需要移动p / Invoke定义。 [STAThread]属性应位于Main()方法上,而不应位于您的p / Invoke定义上。更不用说Main()的文档评论正在应用于SDK_Initialize

所以它应该是这样的:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    static class Program
    {
        [DllImport("project.dll")]
        static extern bool SDK_Initialize(ref uint p_Status );

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}