Сортировка типов C win32 в struct для использования в функции на C#

#c# #c #winapi #marshalling

#c# #c #winapi #сортировка

Вопрос:

Я написал рабочую C DLL. Я хочу использовать его в приложении .NET C #, однако у меня возникают трудности с сортировкой типов, поскольку я не так хорошо знаком с C # и все еще учусь. DLL отлично работает при использовании в написанной на C программе.

Вот заголовок DLL:

 #pragma once

#include <Windows.h>
#include <TlHelp32.h>

#ifdef MYDLL_EXPORTS
    #define MYDLL_API __declspec(dllexport)
#else
    #define MYDLL_API __declspec(dllimport)
#endif

struct clientInfo
{
    HANDLE processHandle = NULL;
    uintptr_t baseAddress = NULL;
};

extern "C" MYDLL_API bool hook(const wchar_t* window_name, const wchar_t* module_name, clientInfo amp;info);
 

По сути, функция открывает дескриптор со всеми правами доступа к данному окну, а также находит базовый адрес модуля для данного имени модуля и помещает их в структуру clientInfo, которая была передана в качестве ссылки в аргументах функции. Возвращает true при успешном выполнении или false, если это не работает.

Реализация этого не является необходимой для моего вопроса, по крайней мере, я думаю. Теперь в приложении .NET Windows Forms C # я установил красивую форму, которая информирует меня, если при нажатии кнопки функция выполнена успешно или не выполнена. С моим кодом C # он компилируется, но не совсем работает. Как мне правильно маршалировать структуру и мою функцию в C #?

Мой не работающий код на C #:

 // Structure marshalling
 [StructLayout(LayoutKind.Sequential)]
 public struct clientInfo
 {
     public IntPtr processHandle;

     [MarshalAs(UnmanagedType.I4)]
     public uint gameBaseAddress;
 };

// Function marshalling
[DllImport("C:\Users\Cira\source\repos\myDll\Debug\myDll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern bool hook(string window_name, string module_name, out clientInfo info);
 

Комментарии:

1. Все выглядит хорошо, кроме строк: docs.microsoft.com/en-us/dotnet/framework/interop /…

2. uint для адреса должен быть UIntPtr. И кодировка должна быть Unicode.

3. Могу только добавить, что путь должен быть относительным или отсутствовать… Вы не можете скомпилировать внутри программы абсолютный путь, подобный тому, который вы написали. Не потому, что компилятор выдаст ошибку, а потому, что вы захотите выполнить на компьютере, на котором нет пользователя Cira 🙂

4. Безусловно, самый простой и надежный способ взаимодействия между машинным кодом и .NET — это C / CLI. Это позволяет создавать сборки в смешанном режиме, которые могут быть немедленно использованы .NET. Вы можете решить, хотите ли вы поместить свой собственный код в эту сборку или связать эту сборку с собственной библиотекой импорта DLL. Подробности см. в разделе Взаимодействие с Native и . NET.