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