简体   繁体   English

在C#中使用DLL问题

[英]Problem using dll in c#

I need to use an unmanaged COM dll in c# program. 我需要在C#程序中使用非托管COM dll。 Dll contains a function, say: DLL包含一个函数,说:

Open(char *name);

But when imported to c# (Project->Add Reference) it is available as: 但是,当导入到c#(“项目”->“添加引用”)中时,它可以作为:

mydll.Open(ref byte name)

How can I pass a string to this function? 如何将字符串传递给此函数?

When I do: 当我做:

byte[] name = new byte[32];
mydll.Open(ref name);

I get compilation error "Cannot convert ref byte[] to ref byte". 我收到编译错误“无法将参考字节[]转换为参考字节”。

If you mean for it to be a string, then in your IDL file, you have to specify that this point represents a string. 如果要使其成为字符串,则必须在IDL文件中指定该点代表字符串。 See this article for information on the [string] attribute: http://msdn.microsoft.com/en-us/library/d9a4wd1h%28v=VS.80%29.aspx If you want to be CLS compliant (and interoperate with scripting languages, you might want to look into using BSTR instead of char* for passing strings). 请参阅本文,以获取有关[string]属性的信息: http : //msdn.microsoft.com/zh-cn/library/d9a4wd1h%28v=VS.80%29.aspx如果您想兼容CLS(并与之兼容)脚本语言,您可能想研究使用BSTR而不是char *来传递字符串)。 This way you'll get unicode support too. 这样,您还将获得unicode支持。

Unless you give COM the hint that this is a string, you will have problems whenever COM has to marshal the parameters (ie across apartment or process boundaries). 除非您向COM暗示这是一个字符串,否则每当COM必须封送参数(即跨越单元或进程边界)时,您都会遇到问题。

This article may also give you a good starting point on C++ / C# / COM goodies: COM Interop Part 1: C# Client Tutorial 本文还可以为您提供有关C ++ / C#/ COM好东西的良好起点: COM Interop第1部分:C#客户端教程

Maybe you can do this... 也许你可以做到...

byte[] bytes = Encoding.ASCII.GetBytes(myString); byte [] bytes = Encoding.ASCII.GetBytes(myString);

You might try decorating that "name" variable with: 您可以尝试使用以下命令装饰该“名称”变量:

[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]

That's a single byte, and I think is compatibel with a single char. 那是一个字节,我与一个字符兼容。 If not, the answer is likely going to be using MarshalAs to make that variable look like type. 如果不是,答案可能是使用MarshalAs使该变量看起来像类型。

Keep in mind you could lose it if the array is not properly terminated. 请记住,如果阵列未正确终止,则可能会丢失它。 Anyhow, I would try passing in the pointer to the first element byte[0] try: 无论如何,我将尝试将指针传递到第一个元素byte [0]:

mydll.Open(ref name[0]); mydll.Open(参考名称[0]);

I'm not sure how the interop will marshal this but it's worth a try. 我不确定互操作员如何将其编组,但这值得一试。

The import is not correct. 导入不正确。 You can import it manually: 您可以手动导入:

[DllImport("<Your COM Dll>")]
private static extern <Return Type> <"Function Name">();

Then, in your main method, or in the method where you initialize your dll object, you need: 然后,在您的main方法或初始化dll对象的方法中,您需要:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr LoadLibrary(string lpFileName);

public MyDll()
{
    Environment.CurrentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    string dllPath = Environment.CurrentDirectory + @"<Location of Dll you are importing from>";
    LoadLibrary(dllPath);
}

For example, check out the following COM Dll: 例如,签出以下COM Dll:

GOIO_DLL_INTERFACE_DECL gtype_int32 GoIO_GetNthAvailableDeviceName(
char *pBuf,         
gtype_int32 bufSize,
gtype_int32 vendorId,   
gtype_int32 productId,  
gtype_int32 N);

I imported this Dll as the following: 我将这个Dll导入如下:

[DllImport("GoIO_DLL.dll")]
private static extern int GoIO_GetNthAvailableDeviceName(
byte[] pBuf, 
int bufSize, 
int vendorId,
int productId,
int N);

As you can see, the char pointer becomes a byte[], just like you tried. 如您所见,char指针变成了byte [],就像您尝试过的那样。 There is no need for the ref keyword. 不需要ref关键字。

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

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