Chamar um tipo personalizado a partir de uma DLL escrito em C ++ a partir de c #
-
18-09-2019 - |
Pergunta
Eu estou usando uma DLL escrito em C ++ no meu projeto C #. Eu tenho sido capaz de chamar funções dentro da DLL usando este código:
[DllImport("hidfuncs", EntryPoint = "vm_hid_scan", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr VmHidScan();
Agora eu preciso chamar uma função que requres um ponteiro de tipo personalizado. Os Docs para o DLL layout da função como esta:
hid_get_info(int n,PDEV_INFO *pdi)
Eu não sei como usar este ponteiro personalizado. É este definido na DLL? Se sim, como pode usá-lo a partir do projeto C #? Se não eu preciso incluir o arquivo de cabeçalho no c #? Agradeço antecipadamente por sua ajuda.
Solução
Dado o "P" prefixo, parece que a declaração real é
hid_get_info(int n, DEV_INFO **pdi)
onde DEV_INFO é uma estrutura. Você precisa encontrar a declaração desta estrutura e adicioná-lo ao seu código C # com o atributo [StructLayout]. Você iria em seguida, declarar a função como esta em seu código C #:
[DllImport("blah.dll")]
private static extern something hid_get_info(int n, out IntPtr pdi);
e utilização Marshal.PtrToStructure () para obter o valor da estrutura. Espero que você não tem que liberar a estrutura, você estaria ferrado.
Uma segunda interpretação é que "PID" retorna uma matriz de ponteiros para estruturas DEV_INFO. Pouco provável, dado o argumento de "n", o que poderia significar o número de elementos na matriz que você passar a ser preenchido pela função. Nesse caso, passar um IntPtr [] e "n" ao seu comprimento.
Outras dicas
Você precisa criar um struct
em C # que espelha o C ++ PDEV_INFO
struct
em C ++.
Você deve aplicar [StructLayout(LayoutKind.Sequential)]
para a estrutura e, em seguida, copiar os campos da struct C ++ (veja o arquivo de cabeçalho) em ordem.
Você pode então escrever um método extern
que leva o struct
como parâmetro ref
.
Eu vou assumir com segurança PDEV_INFO*
é um DEV_INFO**
.
Use isso em C #:
class DEV_INFO
{
// fields go here
}
static class NativeMethods
{
[DllImport...]
public static extern int hid_get_info(int n, ref DEV_INFO pdi);
}