1 生成tli和tlh

  1. #import "tr.dll"
  2. int main()
  3. {
  4. return 0;
  5. }

运行此程序, 在配置路径下就生成了tr.tlh和tr.tli, 相当于h文件和cpp文件
image.png
然后打开tr.tlh,把后面改为相对路径, 然后把这两个文件剪切到项目目录
image.png

2 写免注册代码

注意:
C++可以用这种方法, 但这种方法不能写在dll里给python调用。
原因:直接从DLL使用COM组件,会绕过Windows COM库的套间机制,从而会使一些功能得不到响应。这样是不推荐的,相当于又回到了平坦的接口直接调用。
一般这种用法只在DLL中所有组件是自由线程模型以及所有跟这些组件交互的组件也是自由线程模型时才会正常工作,否则就不会正常工作。

(1) 法一

  1. #include "tr.tlh"
  2. #include <windows.h>
  3. #include <iostream>
  4. using std::cout;
  5. using std::endl;
  6. template <typename T>
  7. T FreeRegCom(const wchar_t* FilePath, CLSID& clsid)
  8. {
  9. // 首先加载dll, 获取dll首地址
  10. HMODULE com_module = LoadLibraryW(FilePath);
  11. if (NULL == com_module)
  12. {
  13. cout << "获取模块地址失败!" << endl;
  14. return NULL;
  15. }
  16. // 获取DllGetClassObject函数地址
  17. using Get = HRESULT (__stdcall*)(REFCLSID, REFIID, LPVOID*);
  18. Get DllGetClassObject = (Get)(GetProcAddress(com_module, "DllGetClassObject"));
  19. if (NULL == DllGetClassObject)
  20. {
  21. cout << "获取函数地址失败!" << endl;
  22. return NULL;
  23. }
  24. // 获取工厂指针
  25. IClassFactory* pcf = NULL;
  26. HRESULT hr = DllGetClassObject(clsid, IID_IClassFactory, (LPVOID*)&pcf);
  27. if (FAILED(hr)||NULL==pcf)
  28. {
  29. cout << "获取工厂失败!" << endl;
  30. return NULL;
  31. }
  32. // 创建实例对象指针
  33. T com = nullptr;
  34. hr = pcf->CreateInstance(NULL, __uuidof(std::remove_pointer<T>::type), (LPVOID*)&com);
  35. if (FAILED(hr) || com == nullptr)
  36. {
  37. cout << "获取com组件实例失败!" << endl;
  38. return NULL;
  39. }
  40. // 释放工厂指针, 返回实例对象指针
  41. pcf->Release();
  42. return com;
  43. }
  44. int main()
  45. {
  46. CoInitialize(NULL);
  47. CLSID clsid;
  48. HRESULT hr = CLSIDFromString(L"{d0ffd076-d72e-498e-9bb3-22f599eb5789}", &clsid);
  49. if (FAILED(hr))
  50. {
  51. cout << "获取CLSID失败!" << endl;
  52. return 0;
  53. }
  54. TURING::_FISR* com = FreeRegCom<TURING::_FISR*>(L"tr.dll", clsid);
  55. std::cout << com->Version() << std::endl;
  56. std::cout << com->About() << std::endl;
  57. CoUninitialize();
  58. system("pause");
  59. return EXIT_SUCCESS;
  60. }

(2) 法二

  1. #include "tr.tlh"
  2. #include <windows.h>
  3. #include <iostream>
  4. using std::cout;
  5. using std::endl;
  6. template <typename T>
  7. T FreeRegCom(const wchar_t* FilePath)
  8. {
  9. // 首先加载dll, 获取dll首地址
  10. HMODULE com_module = LoadLibraryW(FilePath);
  11. if (NULL == com_module)
  12. {
  13. cout << "获取模块地址失败!" << endl;
  14. return NULL;
  15. }
  16. // 获取DllGetClassObject函数地址
  17. using Get = HRESULT (__stdcall*)(REFCLSID, REFIID, LPVOID*);
  18. Get DllGetClassObject = (Get)(GetProcAddress(com_module, "DllGetClassObject"));
  19. if (NULL == DllGetClassObject)
  20. {
  21. cout << "获取函数地址失败!" << endl;
  22. return NULL;
  23. }
  24. // 获取工厂指针
  25. IClassFactory* pcf = NULL;
  26. HRESULT hr = DllGetClassObject(__uuidof(TURING::FISR), IID_IClassFactory, (LPVOID*)&pcf);
  27. if (FAILED(hr)||NULL==pcf)
  28. {
  29. cout << "获取工厂失败!" << endl;
  30. return NULL;
  31. }
  32. // 创建实例对象指针
  33. T com = nullptr;
  34. hr = pcf->CreateInstance(NULL, __uuidof(TURING::_FISR), (LPVOID*)&com);
  35. if (FAILED(hr) || com == nullptr)
  36. {
  37. cout << "获取com组件实例失败!" << endl;
  38. return NULL;
  39. }
  40. // 释放工厂指针, 返回实例对象指针
  41. pcf->Release();
  42. return com;
  43. }
  44. int main()
  45. {
  46. CoInitialize(NULL);
  47. TURING::_FISR* com = FreeRegCom<TURING::_FISR*>(L"tr.dll");
  48. std::cout << com->Version() << std::endl;
  49. std::cout << com->About() << std::endl;
  50. CoUninitialize();
  51. system("pause");
  52. return EXIT_SUCCESS;
  53. }