Вызов пользовательского типа из DLL, написанной на C++, из C#
-
18-09-2019 - |
Вопрос
В своем проекте на C# я использую DLL, написанную на C++.Мне удалось вызвать функции внутри DLL, используя этот код:
[DllImport("hidfuncs", EntryPoint = "vm_hid_scan", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr VmHidScan();
Теперь мне нужно вызвать функцию, которой требуется указатель пользовательского типа.Документы для DLL размещают функцию следующим образом:
hid_get_info(int n,PDEV_INFO *pdi)
Я не знаю, как использовать этот пользовательский указатель.Это определено в DLL?Если да, то как его использовать из проекта C#?Если нет, нужно ли мне включать файл заголовка в С#?Заранее спасибо за вашу помощь.
Решение
Учитывая префикс «P», похоже, что настоящее объявление
hid_get_info(int n, DEV_INFO **pdi)
где DEV_INFO — структура.Вам нужно будет найти объявление этой структуры и добавить ее в свой код C# с помощью атрибута [StructLayout].Затем вы объявите такую функцию в своем коде C#:
[DllImport("blah.dll")]
private static extern something hid_get_info(int n, out IntPtr pdi);
и используйте Marshal.PtrToStructure() для получения значения структуры.Надеюсь, вам не придется освобождать конструкцию, иначе вы облажаетесь.
Вторая интерпретация заключается в том, что «pid» возвращает массив указателей на структуры DEV_INFO.Скорее всего, учитывая аргумент «n», который вполне может означать количество элементов в массиве, который вы передаете для заполнения функцией.В этом случае передайте IntPtr[] и задайте «n» для его длины.
Другие советы
Вам необходимо создать struct
в C#, который отражает C++ PDEV_INFO
struct
в С++.
Вам следует подать заявку [StructLayout(LayoutKind.Sequential)]
в структуру, а затем скопируйте поля из структуры C++ (посмотрите файл заголовка) по порядку.
Затем вы можете написать extern
метод, который принимает struct
как ref
параметр.
Я смело предполагаю PDEV_INFO*
это DEV_INFO**
.
Используйте это в С#:
class DEV_INFO
{
// fields go here
}
static class NativeMethods
{
[DllImport...]
public static extern int hid_get_info(int n, ref DEV_INFO pdi);
}