非托管DLL的C#包装器

非托管DLL的C#包装器,c#,wrapper,unmanaged,C#,Wrapper,Unmanaged,首先,我知道如何调用非托管函数。我一直在使用非托管dll中的接口方法。我想,我需要的是写包装纸 请帮我翻译一下真正的代码 我有: 旧DLL(C) 2头文件 lib文件(为什么?) !!没有消息来源 以下是.h文件(兴趣点-声明接口)中的一些代码: 它不是一个COM对象,我想,我不能为这个dll使用类型库导入 我需要的是: 调用BlNetPassCreateA 获取指向接口INetPass的指针 调用接口方法CreateNetPassEnum 我以前就是这样做的(是PInvoke): 好的

首先,我知道如何调用非托管函数。我一直在使用非托管dll中的接口方法。我想,我需要的是写包装纸

请帮我翻译一下真正的代码

我有:

  • 旧DLL(C)
  • 2头文件
  • lib文件(为什么?)
  • !!没有消息来源
以下是.h文件(兴趣点-声明接口)中的一些代码:

它不是一个COM对象,我想,我不能为这个dll使用类型库导入

我需要的是:

  • 调用BlNetPassCreateA
  • 获取指向接口INetPass的指针
  • 调用接口方法CreateNetPassEnum
我以前就是这样做的(是PInvoke):

好的!IntPtr包含一些数据,但接下来是什么?我如何描述后面的接口并调用其方法?

我将创建一个C接口的C#等价物,为所有相应的函数导入dll。您甚至可以定义与C端结构相对应的结构。我将如何做到这一点的示例:

    // This defines a custom datatype present in our dll.
    [StructLayout(LayoutKind.Sequential)]
    public struct MyDllStruct
    {
        int aValue;

        [MarshalAs(UnmanagedType.Bool)]
        bool anotherValue;
    }

    public static class MyDllInterface
    {
        // The function in the interface can be customized by instead             
        // specifying the EntryPoint in the DllImport-attribute.
        [DllImport("MyDll.dll", EntryPoint = "mydll_function")]
        public static extern int MyDllFunction(
                int param1,
            // We want this to become a C-style boolean 
            // (false == 0, true != 0)
                [MarshalAs(UnmanagedType.Bool)]
                bool param2,
            // We want the dll to write to our struct, and to be  
            // able to get the data written to it back we need to 
            // specify the Out-attribute. If we were just feeding the 
            // parameter to the dll we could just use the In-attribute
            // instead, or combine them if we want to achieve both.
                [Out, MarshalAs(UnmanagedType.LPStruct)]
                MyDllStruct resultStruct
            );

        [DllImport("MyDll.dll")]
        // Sometime we need to do a little magic on our own so we let 
        // this function return an IntPtr, and not the struct.
        public static extern IntPtr get_a_pointer_struct();

        // By not defining the EntryPoint-parameter the application 
        // expects that the dll function is named just as the
        // C#-function declaration.
        [DllImport("MyDll.dll")]
        // Here we specify that we are expecting a char-array 
        // back from the function, so the application should
        // marshal it as such.
        [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string mydll_get_errormsg();
    }

    // This class "converts" the C-style functions
    // into something more similar to the common
    // way C# is usually written.
    public class MyDllWrapper
    {
        // Calls the MyDllInterface.MyDllFunction and returns
        // the resulting struct. If an error occured, an
        // exception is thrown.
        public MyDllStruct CallFunction(int param1, bool param2)
        {
            MyDllStruct result = new MyDllStruct();

            int errorCode = MyDllInterface.MyDllFunction(
                                param1, param2, result);

            if (errorCode < 0)
                throw new Exception(String.Format(
                    "We got an error with code {0}. Message: ", 
                    errorCode, MyDllInterface.mydll_get_errormsg()));

            return result;
        }

        // Gets a pointer to a struct, and converts it 
        // into a structure.
        public MyDllStruct GetStruct()
        {
            IntPtr structPtr = MyDllInterface.get_a_pointer_struct();

            return (MyDllStruct)Marshal.PtrToStructure(
                structPtr, typeof(MyDllStruct));
        }
    }

<>我不知道ReFID是什么类型,我们如何为它们获得适当的值,但是我希望这能让你开始解决这个问题。

< P>你应该写一个托管C++包装器来调用C++函数,然后在.NET项目中使用。因为没有正常的方法从.Net调用非托管对象实例上的函数。

DECLARE\u INTERFACE
用于声明COM接口(并且
IUnknown
的存在也是一个很大的赠品)。所以我认为这是一个COM对象。也许你是对的。。。这是一个第三方软件:他们不能给我C#示例,但他们告诉我-你可以编写包装器为什么不尝试添加对这个dll的引用?如果它s COM,它将使用COM生成的包装器导入。如果不是,继续思考:)这不是一个COM组件,我想这里有一个很好的建议。在一些复杂的非托管API中,您可以在C++中创建一个简单的包装器,然后通过代码从pPoECK调用它。或者甚至创建托管C++库,然后从C语言调用它。从你的例子看来,编写C++包装器将是一个简单的任务。在这种情况下,真正的代码更好!但是在我的例子中,首先我需要调用静态函数(BlNetPassCreate),它将参数作为指向接口的指针返回给我。我不知道如何将我现有的指针链接到C#接口实现抱歉,如果我看不到常见的东西(感谢您的耐心和帮助。我无法调用CreateNetPassEnum,因为在DLL“BlNetpassApi\”中-{“找不到入口点\“CreateNetPassEnum\”:“}。它在接口后面(((我给3D派对写了封信……也许他们会说如何写包装器IntPtr某物;Guid temp_Guid=Guid.Empty;IntPtr something 2;int temp_int=BlNetPassCreateA(null,ref temp_Guid,out something);temp_int=CreateNetPassEnum(拿出一些东西2,参考CLSID_火柴盒,参考IID_INetPassEnum);
[DllImport("BlNetpassApi")] 
public static extern int BlNetPassCreateA(string pHostName, ref Guid GUID, out IntPtr rINetPass);

...
...

 IntPtr something; 
 Guid temp_guid = Guid.Empty;

 int temp_int = BlNetPassCreateA(null, ref temp_guid, out something);
    // This defines a custom datatype present in our dll.
    [StructLayout(LayoutKind.Sequential)]
    public struct MyDllStruct
    {
        int aValue;

        [MarshalAs(UnmanagedType.Bool)]
        bool anotherValue;
    }

    public static class MyDllInterface
    {
        // The function in the interface can be customized by instead             
        // specifying the EntryPoint in the DllImport-attribute.
        [DllImport("MyDll.dll", EntryPoint = "mydll_function")]
        public static extern int MyDllFunction(
                int param1,
            // We want this to become a C-style boolean 
            // (false == 0, true != 0)
                [MarshalAs(UnmanagedType.Bool)]
                bool param2,
            // We want the dll to write to our struct, and to be  
            // able to get the data written to it back we need to 
            // specify the Out-attribute. If we were just feeding the 
            // parameter to the dll we could just use the In-attribute
            // instead, or combine them if we want to achieve both.
                [Out, MarshalAs(UnmanagedType.LPStruct)]
                MyDllStruct resultStruct
            );

        [DllImport("MyDll.dll")]
        // Sometime we need to do a little magic on our own so we let 
        // this function return an IntPtr, and not the struct.
        public static extern IntPtr get_a_pointer_struct();

        // By not defining the EntryPoint-parameter the application 
        // expects that the dll function is named just as the
        // C#-function declaration.
        [DllImport("MyDll.dll")]
        // Here we specify that we are expecting a char-array 
        // back from the function, so the application should
        // marshal it as such.
        [return: MarshalAs(UnmanagedType.LPStr)]
        public static extern string mydll_get_errormsg();
    }

    // This class "converts" the C-style functions
    // into something more similar to the common
    // way C# is usually written.
    public class MyDllWrapper
    {
        // Calls the MyDllInterface.MyDllFunction and returns
        // the resulting struct. If an error occured, an
        // exception is thrown.
        public MyDllStruct CallFunction(int param1, bool param2)
        {
            MyDllStruct result = new MyDllStruct();

            int errorCode = MyDllInterface.MyDllFunction(
                                param1, param2, result);

            if (errorCode < 0)
                throw new Exception(String.Format(
                    "We got an error with code {0}. Message: ", 
                    errorCode, MyDllInterface.mydll_get_errormsg()));

            return result;
        }

        // Gets a pointer to a struct, and converts it 
        // into a structure.
        public MyDllStruct GetStruct()
        {
            IntPtr structPtr = MyDllInterface.get_a_pointer_struct();

            return (MyDllStruct)Marshal.PtrToStructure(
                structPtr, typeof(MyDllStruct));
        }
    }
    [DllImport("BlNetPassApi")]
    public static extern void CreateNetPassEnum(IntPtr this, int cid, int reffid);

    ...
    IntPtr something; 
    Guid temp_guid = Guid.Empty;

    int temp_int = BlNetPassCreateA(null, ref temp_guid, out something);

    CreateNetPassEnum(in something, 10, 10);