digitalmars.D - problem with C dll
- bobef (40/40) Mar 16 2005 I'm trying to get a working browser in D app. It is works (extremely slo...
- John C (13/61) Mar 16 2005 There's no reason why you shouldn't be able to get it all working in D.
- Ben Hinkle (26/28) Mar 16 2005 I think it has to do with throwing away the "extern(C)" in the cast. The...
- bobef (5/33) Mar 16 2005 Yes it is. I learned this little trick from undig's scintilla conversati...
- Charles (12/51) Mar 16 2005 Good lord, MFC in D ? How in the world did you manage this ??
- John Reimer (30/35) Mar 16 2005 Like Ben said, this is probably the big part of the problem. "create"
- John Reimer (2/8) Mar 16 2005 Sorry, I meant extern(C).
I'm trying to get a working browser in D app. It is works (extremely slow for me) with core32 library but I could not figure out how to get notified about events (onbeforenavigate, etc) with core32. So now I'm struggling with MFC. I made a dll that does CHtmlView for me, but it does not work. After some time in debuggin I found that the HWND I pass to the dll function is changed in the process, so I tried with a char* and it gets changed too... I find that very strange... any suggestions? Here is some code... MFC: extern "C" __declspec( dllexport ) void* create(char* f) { AfxMessageBox(f); return 0; /*htmlView *view=new htmlView; if(view) { RECT r; GetClientRect(f,&r); CString a; CWnd::FromHandle(f)->GetWindowText(a); AfxMessageBox(a); if(view->Create(0,0,WS_VISIBLE|WS_CHILD,r,CWnd::FromHandle(f),AFX_IDW_PANE_FIRST,0)) { return view; } else { //delete view; //this one crashes return 0; } } return 0;*/ } D: HMODULE dll=LoadLibrary("browser.dll"); create=cast(void* function(char *))GetProcAddress(dll,"create"); destroy=cast(void function(void *))GetProcAddress(dll,"destroy"); //all good so far create("tosho"); //and i get some strage symbols in the messagebox... //if i try to display getwindowtext() it is empty although i've set one (and f is HWND of course)...
Mar 16 2005
"bobef" <bobef_member pathlink.com> wrote in message news:d19c8a$1573$1 digitaldaemon.com...I'm trying to get a working browser in D app. It is works (extremely slow for me) with core32 library but I could not figure out how to get notified about events (onbeforenavigate, etc) with core32. So now I'm struggling with MFC.There's no reason why you shouldn't be able to get it all working in D. core32 doesn't declare IConnectionPoint and the related interfaces needed to attach event sinks. If you've got the SDK, they're in ocidl.h and are straightforward to translate into D. To receive events, you need to implement DWebBrowserEvents2/IDispatch (exdisp.h). This article from MSJ should give you some help http://www.microsoft.com/msj/0698/browser.aspx Specifically the section titled "Sinking events from C++". (If you've got the .NET 2.0 framework installed, fire up Reflector and peek inside the WebBrowser class, although it might be difficult to follow atI made a dll that does CHtmlView for me, but it does not work. After some time in debuggin I found that the HWND I pass to the dll function is changed in the process, so I tried with a char* and it gets changed too... I find that very strange... any suggestions? Here is some code... MFC: extern "C" __declspec( dllexport ) void* create(char* f) { AfxMessageBox(f); return 0; /*htmlView *view=new htmlView; if(view) { RECT r; GetClientRect(f,&r); CString a; CWnd::FromHandle(f)->GetWindowText(a); AfxMessageBox(a); if(view->Create(0,0,WS_VISIBLE|WS_CHILD,r,CWnd::FromHandle(f),AFX_IDW_PANE_FIRST,0)) { return view; } else { //delete view; //this one crashes return 0; } } return 0;*/ } D: HMODULE dll=LoadLibrary("browser.dll"); create=cast(void* function(char *))GetProcAddress(dll,"create"); destroy=cast(void function(void *))GetProcAddress(dll,"destroy"); //all good so far create("tosho"); //and i get some strage symbols in the messagebox... //if i try to display getwindowtext() it is empty although i've set one (and f is HWND of course)...
Mar 16 2005
create=cast(void* function(char *))GetProcAddress(dll,"create"); destroy=cast(void function(void *))GetProcAddress(dll,"destroy");I think it has to do with throwing away the "extern(C)" in the cast. The following example shows a similar bad behavior that is fixed when the type of bar includes the extern(C). extern(C) void* foo(char* p) { printf("foo p %p\n",p); return p; } int main() { // uncomment next two lines to get it working // typeof(&foo) bar; // bar = &foo; // this is the bad version void* function(char*) bar; bar = cast(void* function(char*))&foo; char*p = new char; void* res; printf("before calling anything\n"); printf("p %p\n",p); printf("about to call foo directly\n"); res = foo(p); printf("res %p\n",res); printf("about to call bar\n"); res = bar(p); printf("res %p\n",res); return 0; }
Mar 16 2005
Yes it is. I learned this little trick from undig's scintilla conversation. define function type as extern (C) alias void *(*type)(char *); then cast(type)getprocaddress and all goes smoothly... In article <d19m9o$1h8i$1 digitaldaemon.com>, Ben Hinkle says...create=cast(void* function(char *))GetProcAddress(dll,"create"); destroy=cast(void function(void *))GetProcAddress(dll,"destroy");I think it has to do with throwing away the "extern(C)" in the cast. The following example shows a similar bad behavior that is fixed when the type of bar includes the extern(C). extern(C) void* foo(char* p) { printf("foo p %p\n",p); return p; } int main() { // uncomment next two lines to get it working // typeof(&foo) bar; // bar = &foo; // this is the bad version void* function(char*) bar; bar = cast(void* function(char*))&foo; char*p = new char; void* res; printf("before calling anything\n"); printf("p %p\n",p); printf("about to call foo directly\n"); res = foo(p); printf("res %p\n",res); printf("about to call bar\n"); res = bar(p); printf("res %p\n",res); return 0; }
Mar 16 2005
Good lord, MFC in D ? How in the world did you manage this ?? "bobef" <bobef_member pathlink.com> wrote in message news:d19c8a$1573$1 digitaldaemon.com...I'm trying to get a working browser in D app. It is works (extremely slowforme) with core32 library but I could not figure out how to get notifiedaboutevents (onbeforenavigate, etc) with core32. So now I'm struggling withMFC.I made a dll that does CHtmlView for me, but it does not work. After sometimein debuggin I found that the HWND I pass to the dll function is changed intheprocess, so I tried with a char* and it gets changed too... I find thatverystrange... any suggestions? Here is some code... MFC: extern "C" __declspec( dllexport ) void* create(char* f) { AfxMessageBox(f); return 0; /*htmlView *view=new htmlView; if(view) { RECT r; GetClientRect(f,&r); CString a; CWnd::FromHandle(f)->GetWindowText(a); AfxMessageBox(a);if(view->Create(0,0,WS_VISIBLE|WS_CHILD,r,CWnd::FromHandle(f),AFX_IDW_PANE_F IRST,0)){ return view; } else { //delete view; //this one crashes return 0; } } return 0;*/ } D: HMODULE dll=LoadLibrary("browser.dll"); create=cast(void* function(char *))GetProcAddress(dll,"create"); destroy=cast(void function(void *))GetProcAddress(dll,"destroy"); //all good so far create("tosho"); //and i get some strage symbols in the messagebox... //if i try to display getwindowtext() it is empty although i've set one(and fis HWND of course)...
Mar 16 2005
bobef wrote:D: HMODULE dll=LoadLibrary("browser.dll"); create=cast(void* function(char *))GetProcAddress(dll,"create"); destroy=cast(void function(void *))GetProcAddress(dll,"destroy");Like Ben said, this is probably the big part of the problem. "create" and "destroy" are assigned a function pointer, but that casted function pointer is extern(D) by default. In this case, it likely has to be extern(Windows). So create the variables like this: extern(C) void* function(char *) create; extern(C) void function(void *) destroy; This declaration must be done at module scope, however, because D currently doesn't recognize the "extern" attribute inside functions. If you wanted to make local function pointers, you could easily define a typedef or alias for them at module scope and then declare the variables inside the function with that type: extern(C) alias void* function(char*) FunctionTypeA; extern(C) alias void function(void*) FunctionTypeB; ... void main() { FunctionTypeA create; FunctionTypeB destroy; ... } The above method makes it easy to assign with the cast you intended. This time it should work because the "extern" type correctly matches the calling convention of the function returned by "GetProcAddress": ... create = cast(FunctionTypeA) GetProcAddress(dll, "create"); destroy = cast(FunctionTypeB) GetProcAddress(dll, "destroy"); ... Hope that helps, JJR
Mar 16 2005
John Reimer wrote:Like Ben said, this is probably the big part of the problem. "create" and "destroy" are assigned a function pointer, but that casted function pointer is extern(D) by default. In this case, it likely has to be extern(Windows). So create the variables like this:Sorry, I meant extern(C).
Mar 16 2005