(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/
Monday, December 29, 2014
Calling Win32 DLL from 64-bit WPF through ATL 32-bit Surrogate COM
Saturday, December 27, 2014
Call 3rd party DLL from ATL COM
(1) use tool to generate def and .lib from DLL ( assuming no header file) http://purefractalsolutions.com/show.php?a=utils/expdef (2) VC++ project linker-->input additional dependency (3) declare and use in CPP extern "C" unsigned char Open_USB(); extern "C" unsigned char Accept_LED(int value); extern "C" void Set_Callback(void* pAny); void(__stdcall*p)(int); // calling convention matching far pascal, for most c function //void __cdecl* p; // ptrAny static void __stdcall CB1(int value) {..} instance function would hast this->* so callback must use static to remove this. p = &CB1; ::Open_USB(); ::Accept_LED(0); ::Set_Callback(p); again cannot use __cdecl must use __stdcall. It turns out Calling Conversion even affect [DllImport] when re-target .net 4.0 from .net 4.0, must specify CDecl in DllImports
Thursday, December 25, 2014
Manually add Connection Point support after ATL Simple object wizard already run
After running ATL COM Simple object wizard without check "Connection Points", manual steps are need to add this support. (1) myserver.h---IConnectionPointContainer/Impl, COM_MAP, IEvents #include "ATLProject1_i.h" #include "_IMyServerEvents_CP.h" class ATL_NO_VTABLE CMyServer : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CMyServer, &CLSID_MyServer>, public IConnectionPointContainerImpl<CMyServer>, public CProxy_IMyServerEvents<CMyServer>, public IDispatchImpl<IMyServer, &IID_IMyServer, &LIBID_ATLProject1Lib, /*wMajor =*/ 1, /*wMinor =*/ 0> { BEGIN_COM_MAP(CMyServer) COM_INTERFACE_ENTRY(IMyServer) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IConnectionPointContainer) END_COM_MAP() BEGIN_CONNECTION_POINT_MAP(CMyServer) CONNECTION_POINT_ENTRY(__uuidof(_IMyServerEvents)) END_CONNECTION_POINT_MAP() (2) .\atlproject1\atlproject1\atlproject1.vcxproj.filters -- need one include <ClInclude Include="ATLProject1_i.h"> <Filter>Generated Files</Filter> </ClInclude> <ClInclude Include="_IMyServerEvents_CP.h"> <Filter>Header Files</Filter> </ClInclude> <ClInclude Include="MyServer.h"> <Filter>Header Files</Filter> </ClInclude> </ItemGroup> (3).\atlproject1\atlproject1\atlproject1.vcxproj --- include .h for compiler <ItemGroup> <ClInclude Include="ATLProject1_i.h" /> <ClInclude Include="dllmain.h" /> <ClInclude Include="MyServer.h" /> <ClInclude Include="Resource.h" /> <ClInclude Include="stdafx.h" /> <ClInclude Include="targetver.h" /> <ClInclude Include="xdlldata.h" /> <ClInclude Include="_IMyServerEvents_CP.h" /> </ItemGroup> (4) .\atlproject1\atlproject1\atlproject1.idl -- disinterface and coclass library ATLProject1Lib { importlib("stdole2.tlb"); [ uuid(1D071C81-6C67-458F-9B35-992DBAE162D8) // one of these are duplicate uuid(118E250A-B298-4749-90D8-36C764237BA4) ] dispinterface _IMyServerEvents { properties: methods: }; [ uuid(48A5B08F-ED8F-4F1F-8344-5F7C913FB895) ] coclass MyServer { [default] interface IMyServer; [default, source] dispinterface _IMyServerEvents; }; }; Notes: (n1) to user Connection point, Add Method to _IMyServerEvents (Class View Context Menu) e.g. signature CB(int data). Then Add->Connection point onto CMyServer Class (again Class View Ctx Menu) select _IMyS erverEvents in Source Interface List. Now there will be a function Fire_CB to fire COM Event into WPF client (n2) MyServer.rgs need update ForceRemove {dispinterface _IMyServerEvents GUI in IDL} = s 'MyServer Class' (n3) Content of [project dir]\_IMyServerEvents_CP.h #pragma once using namespace ATL; templateclass CProxy_IMyServerEvents : public IConnectionPointImpl { // WARNING: This class may be regenerated by the wizard public: };
Subscribe to:
Posts (Atom)