digitalmars.D - problem with C dll
- bobef <bobef_member pathlink.com> Mar 16 2005
- "John C" <johnch_atms hotmail.com> Mar 16 2005
- "Ben Hinkle" <bhinkle mathworks.com> Mar 16 2005
- bobef <bobef_member pathlink.com> Mar 16 2005
- "Charles" <cee-lo green.com> Mar 16 2005
- John Reimer <brk_6502 yahoo.com> Mar 16 2005
- John Reimer <brk_6502 yahoo.com> Mar 16 2005
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 at first because C# hides all the COM QueryInterface stuff in ordinary casts.)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
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 slow
me) with core32 library but I could not figure out how to get notified
events (onbeforenavigate, etc) with core32. So now I'm struggling with
I made a dll that does CHtmlView for me, but it does not work. After some
in debuggin I found that the HWND I pass to the dll function is changed in
process, so I tried with a char* and it gets changed too... I find that
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);
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
is 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









"John C" <johnch_atms hotmail.com> 