digitalmars.D.learn - Need help on COM Programming Problem
- Steve Myers (51/51) Jul 24 2008 I have been using D 1.0 for a while (currently using 1.028), mostly in L...
- Koroskin Denis (7/78) Jul 25 2008 Put some logging or debug step-by-step to understand at what line does t...
- Steve Myers (4/93) Jul 25 2008 Thanks for your tips, but no joy. It is failing right at the call to the...
I have been using D 1.0 for a while (currently using 1.028), mostly in Linux. Recently I have moved to Windows as forced by necessity of having to tie in to some custom OCX controls provided by a hardware manufacturer. I have been almost beating my brains out trying to get the COM interface to work correctly fine, but when I use it in D, everything seems to set up properly and then when I call methods of the COM Interface, it either silently fails (no errors reported) or it bombs out with an Access Violation. Here is a simple program in which I call 2 methods of the object and they appear to work (no error), but they actually don't do anything. --------------------------- module test; import std.c.stdio, std.c.stdlib, std.c.windows.windows, std.c.windows.com; import local.utils; GUID IID_ITracker = {0x83d5a123, 0x6857, 0x423b, [0x94, 0x55, 0x8b, 0x89, 0xd5, 0x32, 0xeb, 0xf9]}; GUID CLSID_Tracker = {0x43f7fc01, 0xe47e, 0x473c, [0xaa, 0xdd, 0xe7, 0xe5, 0xd2, 0xe0, 0xb8, 0x41]}; interface ITracker : IUnknown { extern(Windows): int ReadConfig(wchar* filePath); int WriteConfig(wchar* filePath); } int main() { DWORD dwVer; HRESULT hr; ITracker pITracker; hr=CoInitialize(null); //Initialize OLE if (FAILED(hr)) { printf("OLE 2 failed to initialize\n"); return EXIT_FAILURE; } printf("OLE 2 initialized\n"); hr=CoCreateInstance(&CLSID_Tracker, null, CLSCTX_ALL, &IID_ITracker, &pITracker); if (FAILED(hr)) { printf("Failed to create object x%x\n",hr); } else { int g, status; printf("Object created, calling ITracker.ReadConfig(), ITracker = %p\n", pITracker); status = pITracker.ReadConfig(fromString(`"C:\TD\Test\trackerconfig.txt"`)); if (status < 0) printf("Failed! Error = %d\n", status); printf("Calling ITracker.WriteConfig(), ITracker = %p\n", pITracker); status = pITracker.ReadConfig(toBSTR(`E:\trackerconfig.txt`)); if (status < 0) printf("Failed! Error = %d\n", status); fflush(stdout); pITracker.Release(); } CoUninitialize(); return EXIT_SUCCESS; } -------------- I based this off the sample provided with DMD. I have tried to get this working with Juno, DWin and the basic Phobos libraries to no avail. I am certain I must be doing something really stupid, but for the life of me cannot figure it out. I don't post problems often as I can usually find my answers though Google, but this one has me stumped. If someone can please point out what I am doing wrong, I would be eternally grateful. Steve
Jul 24 2008
On Fri, 25 Jul 2008 08:38:11 +0400, Steve Myers <zzmyers gmail.com> wrote:I have been using D 1.0 for a while (currently using 1.028), mostly in Linux. Recently I have moved to Windows as forced by necessity of having to tie in to some custom OCX controls provided by a hardware manufacturer. I have been almost beating my brains out trying to get the COM interface to work correctly in D. The provider of the OCX gives a everything seems to set up properly and then when I call methods of the COM Interface, it either silently fails (no errors reported) or it bombs out with an Access Violation. Here is a simple program in which I call 2 methods of the object and they appear to work (no error), but they actually don't do anything. --------------------------- module test; import std.c.stdio, std.c.stdlib, std.c.windows.windows, std.c.windows.com; import local.utils; GUID IID_ITracker = {0x83d5a123, 0x6857, 0x423b, [0x94, 0x55, 0x8b, 0x89, 0xd5, 0x32, 0xeb, 0xf9]}; GUID CLSID_Tracker = {0x43f7fc01, 0xe47e, 0x473c, [0xaa, 0xdd, 0xe7, 0xe5, 0xd2, 0xe0, 0xb8, 0x41]}; interface ITracker : IUnknown { extern(Windows): int ReadConfig(wchar* filePath); int WriteConfig(wchar* filePath); } int main() { DWORD dwVer; HRESULT hr; ITracker pITracker; hr=CoInitialize(null); //Initialize OLE if (FAILED(hr)) { printf("OLE 2 failed to initialize\n"); return EXIT_FAILURE; } printf("OLE 2 initialized\n"); hr=CoCreateInstance(&CLSID_Tracker, null, CLSCTX_ALL, &IID_ITracker, &pITracker); if (FAILED(hr)) { printf("Failed to create object x%x\n",hr); } else { int g, status; printf("Object created, calling ITracker.ReadConfig(), ITracker = %p\n", pITracker); status = pITracker.ReadConfig(fromString(`"C:\TD\Test\trackerconfig.txt"`)); if (status < 0) printf("Failed! Error = %d\n", status); printf("Calling ITracker.WriteConfig(), ITracker = %p\n", pITracker); status = pITracker.ReadConfig(toBSTR(`E:\trackerconfig.txt`)); if (status < 0) printf("Failed! Error = %d\n", status); fflush(stdout); pITracker.Release(); } CoUninitialize(); return EXIT_SUCCESS; } -------------- I based this off the sample provided with DMD. I have tried to get this working with Juno, DWin and the basic Phobos libraries to no avail. I am certain I must be doing something really stupid, but for the life of me cannot figure it out. I don't post problems often as I can usually find my answers though Google, but this one has me stumped. If someone can please point out what I am doing wrong, I would be eternally grateful. StevePut some logging or debug step-by-step to understand at what line does the access violation take place. Besides, try using `"C:\TD\Test\trackerconfig.txt"`w or toUTF16z(someFileName) instead of fromString(`"C:\TD\Test\trackerconfig.txt"`). Hope this helps.
Jul 25 2008
Koroskin Denis Wrote:On Fri, 25 Jul 2008 08:38:11 +0400, Steve Myers <zzmyers gmail.com> wrote:Thanks for your tips, but no joy. It is failing right at the call to the method for the COM object. The odd part is that some methods cause an Access Violation and some methods just silently fail. I even tried some of the set/get functions and the set appears to work, but then the get function causes an Access Violation. I start thinking that something is wrong with my reference to the vtable or something. I used tlbimpd.exe from the Juno project to generate the interfaces for the OCX. Is there a better way to do this? SteveI have been using D 1.0 for a while (currently using 1.028), mostly in Linux. Recently I have moved to Windows as forced by necessity of having to tie in to some custom OCX controls provided by a hardware manufacturer. I have been almost beating my brains out trying to get the COM interface to work correctly in D. The provider of the OCX gives a everything seems to set up properly and then when I call methods of the COM Interface, it either silently fails (no errors reported) or it bombs out with an Access Violation. Here is a simple program in which I call 2 methods of the object and they appear to work (no error), but they actually don't do anything. --------------------------- module test; import std.c.stdio, std.c.stdlib, std.c.windows.windows, std.c.windows.com; import local.utils; GUID IID_ITracker = {0x83d5a123, 0x6857, 0x423b, [0x94, 0x55, 0x8b, 0x89, 0xd5, 0x32, 0xeb, 0xf9]}; GUID CLSID_Tracker = {0x43f7fc01, 0xe47e, 0x473c, [0xaa, 0xdd, 0xe7, 0xe5, 0xd2, 0xe0, 0xb8, 0x41]}; interface ITracker : IUnknown { extern(Windows): int ReadConfig(wchar* filePath); int WriteConfig(wchar* filePath); } int main() { DWORD dwVer; HRESULT hr; ITracker pITracker; hr=CoInitialize(null); //Initialize OLE if (FAILED(hr)) { printf("OLE 2 failed to initialize\n"); return EXIT_FAILURE; } printf("OLE 2 initialized\n"); hr=CoCreateInstance(&CLSID_Tracker, null, CLSCTX_ALL, &IID_ITracker, &pITracker); if (FAILED(hr)) { printf("Failed to create object x%x\n",hr); } else { int g, status; printf("Object created, calling ITracker.ReadConfig(), ITracker = %p\n", pITracker); status = pITracker.ReadConfig(fromString(`"C:\TD\Test\trackerconfig.txt"`)); if (status < 0) printf("Failed! Error = %d\n", status); printf("Calling ITracker.WriteConfig(), ITracker = %p\n", pITracker); status = pITracker.ReadConfig(toBSTR(`E:\trackerconfig.txt`)); if (status < 0) printf("Failed! Error = %d\n", status); fflush(stdout); pITracker.Release(); } CoUninitialize(); return EXIT_SUCCESS; } -------------- I based this off the sample provided with DMD. I have tried to get this working with Juno, DWin and the basic Phobos libraries to no avail. I am certain I must be doing something really stupid, but for the life of me cannot figure it out. I don't post problems often as I can usually find my answers though Google, but this one has me stumped. If someone can please point out what I am doing wrong, I would be eternally grateful. StevePut some logging or debug step-by-step to understand at what line does the access violation take place. Besides, try using `"C:\TD\Test\trackerconfig.txt"`w or toUTF16z(someFileName) instead of fromString(`"C:\TD\Test\trackerconfig.txt"`). Hope this helps.
Jul 25 2008