Получить структуры из DLL без промежуточного кода - C#

Узнай цену своей работы

Формулировка задачи:

Есть нативная длл. Для работы с длл необходимо написать программу на С# . Имеется описание структур. там их много, укажу только две.
Листинг программы
  1. #ifndef __IFactory_h__
  2. #define __IFactory_h__
  3. struct IFactory
  4. {
  5. virtual void* __stdcall Create(TCHAR*, void*) = 0;
  6. };
  7. #endif
Листинг программы
  1. struct IEasyDriver
  2. {
  3. virtual unsigned __stdcall AddRef() = 0;
  4. virtual unsigned __stdcall Release() = 0;
  5. // return > 0 if success
  6. // return == 0 if operation not support
  7. // return < 0 if error, return IEASYDRIVER_ERROR_... code, call GetLastError() function for details
  8. virtual int __stdcall IO(ParametersBase*) = 0;
  9. };
Пример С++:
Листинг программы
  1. IFactory* PCIFactory = NULL;
  2. IEasyDriver* m_pPCI = NULL;
  3. // здесь LoadLibrary(szPath);
  4. //Загружаем драйвер устройства
  5. PCIFactory = (IFactory*)GetProcAddress(m_hLib, szExportName);
  6. if(PCIFactory == 0)//Если устройство не загрузилось
  7. {
  8. cout<<"Can not load device"<<endl;
  9. return 0;
  10. }
  11. //Создаем интерфейс для работы с драйвером
  12. m_pPCI = (IEasyDriver*)PCIFactory->Create(_T("IEasyDriver"), 0);
  13. if(m_pPCI == 0)//Если интерфейс не создался
  14. {
  15. cout<<"Can not create IEasyDriver"<<endl;
  16. return 0;
  17. }
Смотрим длл утилитой dumpbin ordinal hint RVA name 3 0 00001A40 DllRegisterServer 4 1 00001B50 DllUnregisterServer 1 2 000125B4

StaticFactory

2 3 000019D0 _DllMain@12 Сможем получить только указатель на структуру, больше ничего не экспортируется. Реализации методов у нас нет. Как быть? Написал промежуточный код на С++ ,точнее на C++/CLI для удобства, но не важно получилась дополнительная сборка.
Листинг программы
  1. #include "IEasyDriver.h"
  2. #include "IFactory.h"
  3. #include "WrEasyDriver.h"
  4. #include "MeConvert.h"
  5. using namespace System;
  6. public ref class WrFactory
  7. {
  8. private:
  9. IFactory * pFactory;
  10.  
  11. public: WrFactory(IFactory * _pFactory)
  12. {
  13. pFactory = _pFactory;
  14. }
  15. WrFactory(IntPtr _ptr)
  16. {
  17. pFactory = static_cast<IFactory *>(_ptr.ToPointer());
  18. }
  19. WrFactory()
  20. {
  21. pFactory = 0;
  22. }
  23. public:
  24. static WrFactory^ PtrToFactory(IntPtr _ptr)
  25. {
  26. return gcnew WrFactory(_ptr);
  27. }
  28. WrEasyDriver^ Create( System::String^ InterfaceName, System::IntPtr pReserved)
  29. {
  30. if( !pFactory)
  31. return nullptr;
  32. char chInterfaceName[100];
  33. MeConvert::ConvertStr(InterfaceName,chInterfaceName);
  34. IEasyDriver* pEasyDriver = static_cast<IEasyDriver*>( pFactory->Create(chInterfaceName,0));
  35. return gcnew WrEasyDriver(pEasyDriver);
  36. }
  37. }; #pragma once
  38. #include "WrParametersBase.h"
  39. #include "IEasyDriver.h"
  40. using namespace System;
  41. public ref class WrEasyDriver
  42. {
  43. IEasyDriver* pEasydriver;
  44. public:
  45. WrEasyDriver(IntPtr _ptr)
  46. {
  47. pEasydriver = static_cast<IEasyDriver*>(_ptr.ToPointer());
  48. }
  49.  
  50. WrEasyDriver(IEasyDriver* _pEasydriver)
  51. {
  52. pEasydriver = _pEasydriver;
  53. }
  54. public: WrEasyDriver()
  55. {
  56. pEasydriver = 0;
  57. }
  58.  
  59. static WrEasyDriver^ PtrToDriver(IntPtr _ptr)
  60. {
  61. return gcnew WrEasyDriver(_ptr);
  62. }
  63. public: unsigned AddRef()
  64. {
  65. if( ! pEasydriver )
  66. return 0;
  67. return pEasydriver->AddRef();
  68. }
  69. public: unsigned Release()
  70. {
  71. if( ! pEasydriver )
  72. return 0;
  73. return pEasydriver->Release();
  74. }
  75.  
  76. // return > 0 if success
  77. // return == 0 if operation not support
  78. // return < 0 if error, return IEASYDRIVER_ERROR_... code, call GetLastError() function for details
  79. //virtual int __stdcall IO(ParametersBase*) = 0;
  80. public: int IO(IParametersBase^ _iParametersBase)
  81. {
  82. ParametersBase paramBase;
  83. paramBase.m_nType = _iParametersBase-> m_nType;
  84. paramBase.m_nSizeOf = _iParametersBase->m_nSizeOf;
  85. return pEasydriver->IO(&paramBase);
  86. }
  87. };
И это работает
Листинг программы
  1. WrFactory PCIFactory = null;
  2. WrEasyDriver m_pPCI = null;
  3.  
  4. IntPtr m_hLib;
  5. string szPath = "SampleDLL.dll";
  6. string szExportName = "StaticFactory";
  7. m_hLib = LoadLibrary(szPath);
  8. if (m_hLib == IntPtr.Zero)
  9. {
  10. Console.WriteLine("Can not load Library");
  11. FreeLibrary(m_hLib);
  12. return;
  13. }
  14.  
  15. IntPtr ptfactory = (IntPtr)GetProcAddress(m_hLib, szExportName);
  16. PCIFactory = WrFactory.PtrToFactory(ptfactory);
  17. if (PCIFactory == null)//Если устройство не загрузилось
  18. {
  19. Console.WriteLine("Can not load device");
  20. FreeLibrary(m_hLib);
  21. return;
  22. }
  23. else
  24. Console.WriteLine("device loaded.");
  25. //
  26. // //Создаем интерфейс для работы с драйвером
  27. m_pPCI = (WrEasyDriver)PCIFactory.Create("IEasyDriver", IntPtr.Zero);
  28. if (m_pPCI == null)//Если интерфейс не создался
  29. {
  30. Console.WriteLine("Can not create IEasyDriver");
  31. FreeLibrary(m_hLib);
  32. return;
  33. }
  34. else
  35. Console.WriteLine("IEasyDriver created.");
Вывод : Device loaded. IEasyDriver created. Так вот вопрос : Можно ли обойтись без промежуточного кода, Сделать все силами С# без промежуточных ДЛЛ ?

Решение задачи: «Получить структуры из DLL без промежуточного кода»

textual
Листинг программы
  1. [ComImport, Guid("6981C3CD-1874-40E4-9B1F-E998171A9B7C")]
  2. class ProxyClass
  3. {
  4. }
  5.  
  6. void Main()
  7. {
  8.     var proxyClass = new ProxyClass();
  9.     var obj = (ISampleInterface)proxyClass;
  10.     obj.SampleMethod();
  11. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 3.833 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут