Monday, December 29, 2014

Calling Win32 DLL from 64-bit WPF through ATL 32-bit Surrogate COM

(1) How to tell if a DLL is 32-bit or 64-bit

 dumpbin /headers MyServer.dll to tell by file Header x86 or x64

(2) Run 32-Bit COM in surrogate Procese so can be called from 64-bit WPF.(one kind of IPC)
       http://www.gfi.com/blog/32bit-object-64bit-environment/ 


 
  • Locate your COM object GUID under the HKey_Classes_Root\Wow6432Node\CLSID\[GUID]
  • Once located add a new REG_SZ (string) Value. Name should be AppID and data should be the same COM object GUID you have just searched for
  • Add a new key under HKey_Classes_Root\Wow6432Node\AppID\ The new key should be called the same as the com object GUID
  • Under the new key you just added, add a new REG_SZ (string) Value, and call it DllSurrogate. Leave the value empty
  • Create a new Key under HKey_Local_Machine\Software\Classes\AppID\ Again the new key should be called the same as the COM object’s GUID. No values are necessary to be added under this key.
  • (3) Step-by-step ALT 32-bit COM Creation (check to make sure project properties are x86) http://msdn.microsoft.com/en-us/library/dssw0ch4%28d=printer,v=vs.90%29.aspx http://msdn.microsoft.com/en-us/library/9yb4317s.aspx Note that C# COM is not usable in (2), especially HKey_Classes_Root\Wow6432Node\CLSID\[GUID] is not there. Also each build of ATL COM project will override this location and need to add back AppID={Guid} (4) A good overall review of 64-bit calling 32-bit using IPC http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/ (5) Dynamic Loading Win32 DLL to access its functions: #pragma hdrstop #pragma package(smart_init) // CObject1 HINSTANCE hMWXUSB=0; typedef int (__cdecl *MYPROC)(LPWSTR); typedef unsigned char (ACCEPT_LED)(int data); ACCEPT_LED *lpacceptled; typedef unsigned char (OPEN_USB)(void); OPEN_USB *lpopenusb; STDMETHODIMP CObject1::get_GetANum(SHORT* pVal) { hMWXUSB=LoadLibrary(L"MWXUSB.DLL"); MYPROC Accept_LED; //Accept_LED = (MYPROC) GetProcAddress(hMWXUSB, "Accept_LED"); if( (hMWXUSB = LoadLibrary(L"MWXUSB.DLL")) == NULL ) { *pVal=-5; return S_OK; } if( (lpopenusb=(OPEN_USB*)GetProcAddress(hMWXUSB,"Open_USB" ))==NULL ) { *pVal=-6; return S_OK; } unsigned char ucOpen; ucOpen = (*lpopenusb)(); if( (lpacceptled=(ACCEPT_LED*)GetProcAddress(hMWXUSB,"Accept_LED" ))==NULL ) { *pVal=-1105; return S_OK; } unsigned char ch; ch = (*lpacceptled)(1); if(ch) { *pVal=-2105; return S_OK; } *pVal=105; return S_OK; }

    No comments: