|
Hi everybody,
Is ther a way [read: a program] to find out what functions a dll is exporting? Is there a tool with MVS that can do this?
To learn more about this I chose the default implementation of a sample dll in VC++: New->Projects->Win32 dynamic link-library.
Now, there's a test function called fnDllTest (my project is called DllTest) which is exported like this:
__declspec(dllexport) int fnDllTest(void)
{
return 42;
}
Now, I created a simple console application which should call this dll function. I loaded the dll using LoadLibrary and that works fine... BUT, now I wish to get the function fnDllTest through the use of GetProcAddress but I can't seem to get it working!
If the dll and the console app loading the dll are residing in the same place then the call to GetProcAddress should look like this right?
blabla = (blabla)GetProcAddress(libPtr, "fnDllTest");
where libPtr is the return value of LoadLibrary... What kind of type should blabla be of?
I haven't found any documentation on how to call dll exported functions...
Thx for all your help,
/Tommy
|
|
|
|
|
find the tool called DUMPBIN. it will tell you the function names. i'm not sure if it can tell you the params, tho.
-c
Smaller Animals Software, Inc.
Few things are harder to put up with than the annoyance of a good example.
Mark Twain
|
|
|
|
|
Thx!
I tried and this was the result:
...
ordinal hint RVA name
1 0 0000100A ?fnDllTest@@YAHXZ
...
What does this tell me? I can't very likely do like this, or...?
... GetProcAddress(libPtr, "?fnDllTest@@YAHXZ");
I mean, there must be a way for me to know what the exporting function name will look like when it is me writing them...?
THx for your help!
/Tommy
|
|
|
|
|
blabla will be a function pointer that is the same type as the function that you are loading. This is why it is hard to use functions in a dll without a header file or good documentation.
In the example that you have given, here would be the function pointer that you would declare:
int (fnDllTestPtr*)(void);
fnDllTestPtr becomes the name of the function pointer type. To use this you would now call this:
fnDllTestPtr fnDllTest = (fnDllTestPtr)GetProcAddress(libPtr, "fnDllTest);
As far as determining which functions are exported pragmatically, you will need to traverse the PE file structure of the DLL in order to read the exports section. Lookup Mike Peitrics article on the PE file format. He created a smaple program called PEDump.
|
|
|
|
|
No, that can't be right...
It crashed when I tried to do that... I mean, shouldn't there be a typedef somewhere?
|
|
|
|
|
Hi again,
Shouldn't it be:
int (*fnDllTestPtr)(void);
and then
fnDllTestPtr = (???)GetProcAddress(libPtr, "fnDllTest");
but I don't know what to put in '???'...
/Tommy
|
|
|
|
|
I am sorry, this is the correct declaration for the function pointer. Typedef it so that you can use it later.
typedef int(*fnDllTestPtr)(void);
Also, if you do not encapsulate the function that you are exporting with extern "c"{ }, then the function will be name mangled, and you will have to include the mangled name in order to load it. So for the function that you have sent in, it should be managled like this:
?fnDllTest@@YAHXZ
Before you attempt to call the function, you should check the return value from GetProcAddress to insure that the function was found and properly pointed to. If the function fails, it will return NULL.
Here is the code that you should use.
typedef int(*fnDllTestPtr)(void);
fnDllTestPtr fp = (fnDllTestPtr)::GetProcAddress(libPtr, "?fnDllTest@@YAHXZ");
if (NULL == fp)
{
MessageBox(NULL, "an error has occurred. The function did not load.", "error", MB_OK);
}
else
{
int i = fp();
}
|
|
|
|
|
Thx Kilowatt! It worked!
But how on earth can it be possible to conclude the above code from the documentation?!?!
First of all; how can this assignment work? Isn't fnDllTestPtr a function pointer variable...?
But again, thx!
/Tommy
|
|
|
|
|
Move casting to left side of assignment:
EDIT - it should be FARPROC &
(FARPROC & )fnDllTestPtr = GetProcAddress(...);
Tomasz Sowinski -- http://www.shooltz.com
- It's for protection - Protection from what? Zee Germans?
|
|
|
|
|
Use Dependency Walker (depends). There is a (usually old) version in the Platform SDK. You can get the latest version from http://www.dependencywalker.com.
|
|
|
|
|
The function name in a DLL can be viewed using Dependency Walker that comes along with Microsoft Developer Studio 6.0. It shows as Depends in the tools panel of Developer studio
Sanjay Mishra
|
|
|
|
|
Background...
I'm using the msado15.dll ADO type library for database access.
I'm using a class derived from CADORecordBinding to bind to a _RecordsetPtr object, which I'm using to update a list view with. The class is given below.
I'm currently reading the MailID field out of the database as an adVariant type, but it's actually an adGUID type.
The reason I'm reading as an adVariant, is that I'm not sure how to store an adGUID type as a c/c++ variable.
I'm a bit new to all this, so please forgive my greenness!
Destroying the CMessageHeadersCache Object...
You'll notice that there are COleVariant member variables in the CMessageHeadersCache class. When I call delete on objects this class, the program crashes! When the COleVariant member variables are absent, deallocation goes just fine! I'm sure that there must be some safe/correct/appropriate way of deallocating these objects containing COleVariants, but I'm a bit stuck! Please help!
Many thanx,
funBag
#pragma once
#include "icrsint.h"
// ============================================================================
// Class CMessageHeadersCache
// Purpose ADO Record binding for the Messsage Headers list view object.
// History funbag 24th March 2002 Initial Rev.
// ============================================================================
class CMessageHeadersCache : public CADORecordBinding
{
public:
CMessageHeadersCache();
~CMessageHeadersCache();
BEGIN_ADO_BINDING(CMessageHeadersCache)
// DateTimeReceived
ADO_VARIABLE_LENGTH_ENTRY2(1,
adVariant,
DateTimeReceived,
sizeof(DateTimeReceived),
status[0],
FALSE)
ADO_VARIABLE_LENGTH_ENTRY2(2,
adVarChar,
SenderMailAddress,
sizeof(SenderMailAddress),
status[1],
FALSE)
ADO_VARIABLE_LENGTH_ENTRY2(3,
adVarChar,
SubjectLine,
sizeof(SubjectLine),
status[2],
FALSE)
ADO_VARIABLE_LENGTH_ENTRY2(4,
adVarChar,
Opened,
sizeof(Opened),
status[3],
FALSE)
ADO_VARIABLE_LENGTH_ENTRY2(5,
adVariant,
MailID,
sizeof(MailID),
status[4],
FALSE)
END_ADO_BINDING()
public:
COleVariant DateTimeReceived;
char SenderMailAddress[100];
char SubjectLine[1024];
char Opened[2];
COleVariant MailID;
ULONG status[5];
};
skydiving....if at first you don't succeed, you're fecked!
|
|
|
|
|
How to get a pointer of the view object into mainframe?
|
|
|
|
|
This code is by Craig Henderson:
CView *GetActiveView(void)
{
CFrameWnd *pFrameWnd;
pFrameWnd = (CFrameWnd *)AfxGetMainWnd();
if (pFrameWnd != NULL && pFrameWnd->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)))
pFrameWnd = ((CMDIFrameWnd *)pFrameWnd)->GetActiveFrame();
return (pFrameWnd == NULL)? NULL : pFrameWnd->GetActiveView();
}
This function will always return the active view in an SDI or MDI application.
Mazy
"So,so you think you can tell,
Heaven from Hell,
Blue skies from pain,...
How I wish,how I wish you were here." Wish You Were Here-Pink Floyd-1975
|
|
|
|
|
Also you can check this
Mazy
"So,so you think you can tell,
Heaven from Hell,
Blue skies from pain,...
How I wish,how I wish you were here." Wish You Were Here-Pink Floyd-1975
|
|
|
|
|
Hi,
Im trying to profile some code to determine where to concentrate in order to speed things up. Obviously i want time statistics. This is the first time ive tried to use profiling. I've successfully generated a pbt file, and im trying to convert this to a text file using PLIST. I can produce function coverage output fine, but whenever i attempt to produce time statistics, PLIST gives me the following error.
PLIST : warning PRF4481: clock frequency is zero
I can assure you, my clock frequency is not zero....Does the profiler have difficulties with GHz machines, or am i doing something stupid or....?
Any suggestions are welcome.
Thanks,
Alex
|
|
|
|
|
Have you merged the .PBO file yet? Perhaps doing a 'prep /M filename' will fix it. Otherwise I don't know...
/moliate
|
|
|
|
|
Hi,
I think there is some kind of limit to the number of characters that can be displayed in a status bar. It seems to be 127 characters. I was wondering if there was any way of increasing this? It doesn't matter how wide I make the status bar, the text is always cut off at that limit!! Really frustrating.
Thanks in advance
(by the way, I know it's not my string variable that's cut off, 'cause I checked)
Mandy
|
|
|
|
|
From the MSDN docs for SB_SETTEXT:
"The text for each part is limited to 127 characters."
You may try to host a static control as a statusbar child.
Tomasz Sowinski -- http://www.shooltz.com
- It's for protection - Protection from what? Zee Germans?
|
|
|
|
|
I have a dialog based app and I create a new dialog in the resource editor. In the main dialog. I put a button that will show the new created dialog, like this:
CTheDialogDlg dlg;
dlg.DoModal();
But now I want to press some more buttons on the main dialog or edit some edit controls... But it's not allowed... Hot make it possible!?
I've tried making it WS_CHILD and try making the parent window to be the desktop window instead of the main window. but it doesn't work... HELP!
------------------------------------
Rickard Andersson, Suza Computing
ICQ#: 50302279
I'm from the winter country SWEDEN!
------------------------------------
|
|
|
|
|
Your problem is that you are showing the dialog as as a modal dialog box. Modal dialog boxes require the focus until they are explicitly closed, a MEssageBox is another type of modal dialog box.
What you want is a modeless dialog box. You can make it appear by calling the Create method of you dialog rather than the DoModal method. When you want the dialog to disappear you can call ShowWindow to hide it, or you can detstroy the dialog when you no longer need it.
|
|
|
|
|
You need to use CTheDialogDlg as modeless. When you call dlg.DoModal, main dialog becomes disabled until secondary dialog is closed.
Tomasz Sowinski -- http://www.shooltz.com
- It's for protection - Protection from what? Zee Germans?
|
|
|
|
|
DoModal creates a modal dialog, this gives the dialog control until it is closed. You'll need to create a modeless dialog using the Create method and ShowWindow. Have a search on MSDN for Modeless dialogs there will be lots of examples.
Michael
|
|
|
|
|
I'm writting a COM plug-in for a service. I'm able to register and unregister the dll with the service. Even after i unregister the dll I still get that error because the file is still in use. When I check with the service it reports that its not using my dll. I thought that the COM library knew when nothing was using a component and would release it.
I'm adding features and debugging my dll so I have to compile it often. I don't want to reboot my computer each time I want to comple the component. Is there a way to manually release this dll?
|
|
|
|
|
Is it a COM+ app ? It could be getting pooled and need stopping in COM+
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
"I'm somewhat suspicious of STL though. My (test,experimental) program worked first time. Whats that all about??!?!
- Jon Hulatt, 22/3/2002
|
|
|
|