| Thread overview | |||||||||
|---|---|---|---|---|---|---|---|---|---|
  | 
March 16, 2005 problem with C dll | ||||
|---|---|---|---|---|
  | ||||
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)...
 | ||||
March 16, 2005 Re: problem with C dll | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to bobef  | "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)... > >  | |||
March 16, 2005 Re: problem with C dll | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to bobef  | > 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;
}
 | |||
March 16, 2005 Re: problem with C dll | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to bobef  | 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 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_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 f > is HWND of course)... > >  | |||
March 16, 2005 Re: problem with C dll | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to Ben Hinkle  | 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; >} > >  | |||
March 16, 2005 Re: problem with C dll | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to bobef  | 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
 | |||
March 16, 2005 Re: problem with C dll | ||||
|---|---|---|---|---|
  | ||||
Posted in reply to John Reimer  | 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).
 | |||
Copyright © 1999-2021 by the D Language Foundation
 
Permalink
Reply