Проблема с использованием DLL в C # - PullRequest
2 голосов
/ 25 июня 2010

Мне нужно использовать неуправляемую COM DLL в программе на C #. Dll содержит функцию, скажем:

Open(char *name);

Но при импорте в c # (Project-> Add Reference) он доступен как:

mydll.Open(ref byte name)

Как передать строку этой функции?

Когда я делаю:

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

Я получаю ошибку компиляции "Невозможно преобразовать ref byte [] в ref byte".

Ответы [ 5 ]

1 голос
/ 26 июня 2010

Если вы хотите, чтобы это была строка, то в вашем файле IDL вы должны указать, что эта точка представляет строку.См. Эту статью для получения информации об атрибуте [string]: http://msdn.microsoft.com/en-us/library/d9a4wd1h%28v=VS.80%29.aspx Если вы хотите быть CLS-совместимым (и взаимодействовать с языками сценариев, вы можете захотеть использовать BSTR вместо char * для передачи строк).Таким образом, вы также получите поддержку юникода.

Если вы не дадите COM подсказку, что это строка, у вас будут проблемы всякий раз, когда COM должен маршалировать параметры (т. Е. Через границы апартаментов или процессов).

Эта статья также может послужить хорошей отправной точкой для вкусностей C ++ / C # / COM: COM-взаимодействие, часть 1: Учебное пособие по клиенту C #

0 голосов
/ 01 июля 2010

Неправильный импорт.Вы можете импортировать его вручную:

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

Затем, в вашем основном методе или в методе, где вы инициализируете свой объект 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);
}

Например, проверитьследующий COM Dll:

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

Я импортировал этот Dll следующим образом:

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

Как видите, указатель на символ становится байтом [], как вы и пытались.Ключевое слово ref не нужно.

0 голосов
/ 25 июня 2010

Вы можете попытаться украсить эту переменную "name" следующим образом:

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

Это один байти я считаю совместимым с одним символом.Если нет, то ответ, скорее всего, будет использовать MarshalAs, чтобы эта переменная выглядела как тип.

0 голосов
/ 25 июня 2010

Имейте в виду, что вы можете потерять его, если массив не завершен должным образом. В любом случае, я бы попытался передать указатель на первый элемент byte [0] try:

mydll.Open (ref ref [0]);

Я не уверен, как это соберет взаимодействие, но стоит попробовать.

0 голосов
/ 25 июня 2010

Может быть, вы можете сделать это ...

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

...