Получить структуры из DLL без промежуточного кода - C#
Формулировка задачи:
Есть нативная длл. Для работы с длл необходимо написать программу на С# .
Имеется описание структур. там их много, укажу только две.
Пример С++:
Смотрим длл утилитой dumpbin
ordinal hint RVA name
3 0 00001A40 DllRegisterServer
4 1 00001B50 DllUnregisterServer
1 2 000125B4
И это работает
Вывод :
Device loaded.
IEasyDriver created.
Так вот вопрос :
Можно ли обойтись без промежуточного кода,
Сделать все силами С# без промежуточных ДЛЛ ?
#ifndef __IFactory_h__
#define __IFactory_h__
struct IFactory
{
virtual void* __stdcall Create(TCHAR*, void*) = 0;
};
#endifstruct IEasyDriver
{
virtual unsigned __stdcall AddRef() = 0;
virtual unsigned __stdcall Release() = 0;
// return > 0 if success
// return == 0 if operation not support
// return < 0 if error, return IEASYDRIVER_ERROR_... code, call GetLastError() function for details
virtual int __stdcall IO(ParametersBase*) = 0;
}; IFactory* PCIFactory = NULL;
IEasyDriver* m_pPCI = NULL;
// здесь LoadLibrary(szPath);
//Загружаем драйвер устройства
PCIFactory = (IFactory*)GetProcAddress(m_hLib, szExportName);
if(PCIFactory == 0)//Если устройство не загрузилось
{
cout<<"Can not load device"<<endl;
return 0;
}
//Создаем интерфейс для работы с драйвером
m_pPCI = (IEasyDriver*)PCIFactory->Create(_T("IEasyDriver"), 0);
if(m_pPCI == 0)//Если интерфейс не создался
{
cout<<"Can not create IEasyDriver"<<endl;
return 0;
}StaticFactory
2 3 000019D0 _DllMain@12 Сможем получить только указатель на структуру, больше ничего не экспортируется. Реализации методов у нас нет. Как быть? Написал промежуточный код на С++ ,точнее на C++/CLI для удобства, но не важно получилась дополнительная сборка.#include "IEasyDriver.h"
#include "IFactory.h"
#include "WrEasyDriver.h"
#include "MeConvert.h"
using namespace System;
public ref class WrFactory
{
private:
IFactory * pFactory;
public: WrFactory(IFactory * _pFactory)
{
pFactory = _pFactory;
}
WrFactory(IntPtr _ptr)
{
pFactory = static_cast<IFactory *>(_ptr.ToPointer());
}
WrFactory()
{
pFactory = 0;
}
public:
static WrFactory^ PtrToFactory(IntPtr _ptr)
{
return gcnew WrFactory(_ptr);
}
WrEasyDriver^ Create( System::String^ InterfaceName, System::IntPtr pReserved)
{
if( !pFactory)
return nullptr;
char chInterfaceName[100];
MeConvert::ConvertStr(InterfaceName,chInterfaceName);
IEasyDriver* pEasyDriver = static_cast<IEasyDriver*>( pFactory->Create(chInterfaceName,0));
return gcnew WrEasyDriver(pEasyDriver);
}
}; #pragma once
#include "WrParametersBase.h"
#include "IEasyDriver.h"
using namespace System;
public ref class WrEasyDriver
{
IEasyDriver* pEasydriver;
public:
WrEasyDriver(IntPtr _ptr)
{
pEasydriver = static_cast<IEasyDriver*>(_ptr.ToPointer());
}
WrEasyDriver(IEasyDriver* _pEasydriver)
{
pEasydriver = _pEasydriver;
}
public: WrEasyDriver()
{
pEasydriver = 0;
}
static WrEasyDriver^ PtrToDriver(IntPtr _ptr)
{
return gcnew WrEasyDriver(_ptr);
}
public: unsigned AddRef()
{
if( ! pEasydriver )
return 0;
return pEasydriver->AddRef();
}
public: unsigned Release()
{
if( ! pEasydriver )
return 0;
return pEasydriver->Release();
}
// return > 0 if success
// return == 0 if operation not support
// return < 0 if error, return IEASYDRIVER_ERROR_... code, call GetLastError() function for details
//virtual int __stdcall IO(ParametersBase*) = 0;
public: int IO(IParametersBase^ _iParametersBase)
{
ParametersBase paramBase;
paramBase.m_nType = _iParametersBase-> m_nType;
paramBase.m_nSizeOf = _iParametersBase->m_nSizeOf;
return pEasydriver->IO(¶mBase);
}
}; WrFactory PCIFactory = null;
WrEasyDriver m_pPCI = null;
IntPtr m_hLib;
string szPath = "SampleDLL.dll";
string szExportName = "StaticFactory";
m_hLib = LoadLibrary(szPath);
if (m_hLib == IntPtr.Zero)
{
Console.WriteLine("Can not load Library");
FreeLibrary(m_hLib);
return;
}
IntPtr ptfactory = (IntPtr)GetProcAddress(m_hLib, szExportName);
PCIFactory = WrFactory.PtrToFactory(ptfactory);
if (PCIFactory == null)//Если устройство не загрузилось
{
Console.WriteLine("Can not load device");
FreeLibrary(m_hLib);
return;
}
else
Console.WriteLine("device loaded.");
//
// //Создаем интерфейс для работы с драйвером
m_pPCI = (WrEasyDriver)PCIFactory.Create("IEasyDriver", IntPtr.Zero);
if (m_pPCI == null)//Если интерфейс не создался
{
Console.WriteLine("Can not create IEasyDriver");
FreeLibrary(m_hLib);
return;
}
else
Console.WriteLine("IEasyDriver created.");Решение задачи: «Получить структуры из DLL без промежуточного кода»
textual
Листинг программы
[ComImport, Guid("6981C3CD-1874-40E4-9B1F-E998171A9B7C")]
class ProxyClass
{
}
void Main()
{
var proxyClass = new ProxyClass();
var obj = (ISampleInterface)proxyClass;
obj.SampleMethod();
}