Использование C++ dll в C#
Как использовать её в C#? Читал про разные способы, но из-за отсутствия необходимых знаний (пишу преимущественно под PHP), плохо понял что делать в моем случае.
Заранее спасибо.
Проблема даже в другом, не получается у меня перевести программу с Delphi на C#.
C Delphi вобще не знаком, может кто сможет помочь.
Вот пример фрагмента использования dll:
CImportingDLL = class
public
function InitMasterWnd(hWnd: HWND):bool; virtual; stdcall; abstract;
procedure GetScreenshot(); virtual; stdcall; abstract;
end;
ConfigData = class
public
procedure SetConfig(GraphicModeFlag: integer; Directory: string; ShowIndicatorFlag: boolean); virtual; stdcall; abstract;
end;
var
sg_Dll: CImportingDLL;
sg_Config: ConfigData;
function Ret_pCImportingDLL(): CImportingDLL; stdcall; external 'ImportingDll.dll';
function Ret_pConfigData(): ConfigData; stdcall; external 'ImportingDll.dll';
procedure TForm1.Button2Click(Sender: TObject);
begin
sg_Dll := Ret_pCImportingDLL();
sg_Config := Ret_pConfigData();
sg_Dll.InitMasterWnd(Application.Handle);
sg_Config.SetConfig(1, Edit1.Text, true);
end;
При наличии знаний я думаю довольно просто делается, но к сожалению мне время критично.
{
static public void InitMasterWnd(IntPtr hWnd);
static public int GetScreenshot();
}
public abstract class ConfigData
{
static public void SetConfig(int GraphicModeFlag, string Directory, bool ShowIndicatorFlag);
}
[DllImportAttribute("ImportingDll.dll", CharSet = CharSet.Auto)]
private static CImportingDLL Ret_pCImportingDLL();
[DllImportAttribute("ImportingDll.dll", CharSet = CharSet.Auto)]
private static ConfigData Ret_pConfigData();
Visual Studio ругает на строчки после DllImportAttribute:
Ошибка 2 Требуется класс, делегат, перечисление, интерфейс или структура
Может вам стоит сперва C# изучить, раз такие проблемы с базовым синтаксисом (методы можно только в декларациях типов объявлять)?
А по теме, пока вы не приведете примеров сигнатур нативных функций, никто не станет отвечать конкретно.
И, кстати, классы из нативного кода импортировать в C# нельзя - только функции, для более тесного взаимодействия нужно пользоваться MC++.
Конечно, стОит. Но увы время для этой задачи ограниченно.
И, кстати, классы из нативного кода импортировать в C# нельзя - только функции, для более тесного взаимодействия нужно пользоваться MC++.
Я выше привел рабочий пример взаимодействия с dll на Delphi. Неужели там это возможно, а в C# нет?
В том же примере и все функции имеются.
Нет. Использовать из C# классы из нативного кода можно только через COM.
А вообще продемонстрированный код работает лишь при условии, что dll скомпилирована либо Delphi, либо С++Builder-ом. И используется из этих сред, так как для остального мира остается загадкой бинарный ООП-интерфейс.
Раз уж из Delphi вызывается и dll скомпилировано не Delphi и не C++Builder'ом.
Вот такой пример компилируется, но выдает ошибку при запуске:
Не удается загрузить DLL "C:\Tmp\TaksiDLL.dll": Произошел сбой в программе инициализации библиотеки динамической компоновки (DLL). (Исключение из HRESULT: 0x8007045A)
{
public partial class LoginForm : Form
{
public abstract class CImportingDll
{
public abstract void InitMasterWnd(IntPtr hWnd);
public abstract int GetScreenshot();
}
public abstract class CImportingConfigData
{
public abstract void AutoSetConfig(int GraphicModeFlag, string CaptureDir, bool ShowIndicatorFlag);
}
[DllImportAttribute("C:\\Tmp\\ImportingDLL.dll", CharSet = CharSet.Auto)]
static extern CImportingDll Ret_pCImportingDll();
[DllImportAttribute("C:\\Tmp\\ImportingDLL.dll", CharSet = CharSet.Auto)]
static extern CImportingConfigData Ret_pCImportingConfigData();
public LoginForm()
{
InitializeComponent();
CImportingDll sg_Dll = Ret_pCImportingDll();
CImportingConfigData sg_Config = Ret_pCImportingConfigData();
sg_Dll.InitMasterWnd(this.Handle);
sg_Config.AutoSetConfig(1, "C:\\Tmp\\", true);
}
}
Возможно через написание прослойки на MC++.
Или же для этого придется всю dll переделывать?
Или же для этого придется всю dll переделывать?
PInvoke позволяет вызывать простые экспортируемые функции, он не позволяет вызвать методы классов.
Чтобы использовать такие классы нативного кода из .NET необходимо написать обертку для них на MC++, т.е. создать смешаную сборку (содержащую машинный код и IL код). Для этого необходимо точно также экспортировать классы из dll в C++ (статически слиновать) и написать к ним обертку - каждый такой класс обернуть в ref class.
Другой путь - сделать интерфейс работы с dll в C-style, используя хэндлы и/или передавая обычные структуры, в этом случае промежуточный код на MC++ не потребуется.
{
public partial class LoginForm : Form
{
[DllImportAttribute("C:\\Tmp\\ImportingDLL.dll")]
static extern bool ExportInitMasterWnd(IntPtr HWND);
[DllImportAttribute("C:\\Tmp\\ImportingDLL.dll")]
static extern void ExportAutoSetConfig(int GraphicModeFlag, string CaptureDir, bool ShowIndicatorFlag);
[DllImportAttribute("C:\\Tmp\\ImportingDLL.dll")]
static extern void GetScreenshot();
public LoginForm()
{
InitializeComponent();
ExportInitMasterWnd(this.Handle);
ExportAutoSetConfig(1, "C:\\Tmp\\", true);
GetScreenshot();
}
}
Выдает всё тоже:
Не удается загрузить DLL "C:\Tmp\ImportingDLL.dll": Произошел сбой в программе инициализации библиотеки динамической компоновки (DLL).
Дело в том, что свойство Handle в конструкторе может быть не опеределено...
Если даже строчку с Handle закомментировать, остальные дву выдают такую же ошибку.
Вот я и не пойму, дело в реализации на C#, либо в самой dll.