|
1. I don't know
2. Simple answer: use both. Writing the DEF file is a simple task, and using both ensures that using GetProcAddress works at all times. As I recall, there are some problems related to using either the first or the latter, but these problems were remedied by using both at the same time. It was related to the exported symbol ordinals in some way..
3. No. It is enough to give a documentation that describes the exported functions/symbols/classes of your DLL. This can be a plain text file.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Thanks and appreciation for your honest reply.
|
|
|
|
|
xcavin wrote:
1. Why is name mangling required ? (just to support overloaded functions only ? In that case will only overloaded function names are mangled ?)
By mangling, or decorating, the exported functions, C linkers can support class/namespace scope and function overloading, by turning what would be invalid redefinition of the same name into a new definition of a unique name. The C++ language allows function overloading where functions with the same name are only distinguished from one another by the data types of the arguments to the functions. Name decoration enables the linker to distinguish between different versions of overloaded functions because the names of the functions are decorated differently.
xcavin wrote:
2. If i use " __declspec( dllexport )", then do i still need .DEF file ?
With the proper .DEF file EXPORTS section, __declspec(dllexport) is not required. __declspec(dllexport) was added to provide an easy way to export functions from an .EXE or .DLL without using a .DEF file.
Per MSDN:
There are three methods for exporting a definition, listed in recommended order of use:
The __declspec(dllexport) keyword in the source code
An EXPORTS statement in a .DEF file
An /EXPORT specification in a LINK command
All three methods can be used in the same program.
xcavin wrote:
3. If i have a dll with .DEF file, then should i distribute it with my dll so that client can use my dll?
No, it is not required. The .DEF file is used solely by the linker.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
i see it wrapped around strings all the time.
yet i cant determine what exactly it suposed to do.
|
|
|
|
|
It's a C macro that expands to: L"Some String" in a unicode build and "Some String" in a non-unicode build.
|
|
|
|
|
|
I drawed two rectangles in gdi and gdi+ respectively ,which I usded the same Points.However,rectangles showed on the screen were not in the same place.what cause that??
The codes I used were as followed:
(How to initialize the gdi+ in vc++6.0,please reference the articles "Macro to initialize GDI+ in VC6.0 MFC projects [^]"By PJ Arends )
=================================
CxxView::OnInitialUpdate()
{
CSize sizeTotal;
sizeTotal.cx = sizeTotal.cy = 500000000;
//the mapping mode is MM_HIMETRIC
SetScrollSizes(MM_HIMETRIC, sizeTotal);
}
CxxView::OnDraw(CDC* pDC)
{
int nRadius = 1000;
CPoint ptCenter = CPoint(200000,0);
CxxDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//Set the map mode of MM_HIMETRIC
pDC->SetMapMode(MM_HIMETRIC);
//Set the original of window ,so we can see the graphics on the screen
pDC->SetWindowOrg(CPoint(ptCenter.x-2*nRadius,ptCenter.y+2*nRadius));
Graphics graphics(pDC->m_hDC);
// Create a Pen object.
Pen pen(Color(255,0 , 255, 0));
Rect rectgdiplus = Rect(ptCenter.x-nRadius,ptCenter.y-nRadius,2*nRadius,2*nRadius);
//draw rectangle using gdi+
graphics.DrawRectangle(&pen,rectgdiplus);
CRect rect(ptCenter.x-nRadius,ptCenter.y-nRadius
,ptCenter.x+nRadius,ptCenter.y+nRadius);
CPen penNew,*ppenOld;
penNew.CreatePen(PS_SOLID,1,RGB(255,0,0));
pDC->SelectStockObject(NULL_BRUSH);
ppenOld=pDC->SelectObject(&penNew);
//draw another rectangle using gdi
pDC->Rectangle(&rect);
pDC->SelectObject(ppenOld);
TRACE("%d,%d,%d,%d\n",rectgdiplus.GetTop(),rectgdiplus.GetLeft(),rectgdiplus.GetBottom(),rectgdiplus.GetRight());
TRACE("%d,%d,%d,%d\n",rect.top,rect.left,rect.bottom,rect.right);
}
Thanks.
|
|
|
|
|
Hello,
Does anyone know if it is possible for my application to monitor port 110 traffic? That is, is it possible to know when a resident mail client has sent a request to 110? I don't want a proxy but I need my program to take some actions if a user has requested a mail download.
It would be nice to know if messages are in fact coming in from such a request, but this is not absolutely necessary.
Thanks,
Murrah Boswell
|
|
|
|
|
In my MFC application (VC6 C++) I maintain multiple
view's. I have a split view and multiple
tabbed views (only one tab view visable at a time)
Two separate view classes derived from CScrollView
in a single document interface.
I have implimented scrolling that works very well in
both view classes. When I switch the focus from one
veiw to the other, the scroll bars snap to zero in the
view that has lost focus.
I have implimented a post problem workaround that repositions
the scroll slider. But the scroll bars flash as they
display the zero setting, then are repositioned back to the
users setting.
Hopefully someone will give me an idea where to look to
stop the zeroing of the scroll bars. (A pre rather
than post solution.)
WedgeSoft
|
|
|
|
|
One way to try to track this problem is to have one, and only one, function calling SetScrollPos in each view. Add some dummy code checking for a zero value, something like
...SetScrollbarPositions...
{
if( newpos == 0 )
{
int a = 0;
}
Run your application. Scroll one of the views. Switch to the debugger. Set a breakpoint at int a = 0 . Switch to the app. Do the stuff that resets the scrollbar. Check the callstack in the debugger to see where it was called from. Problem most likely solved
The slightly clumsy addition of extra code is to avoid (perhaps) a billion legal breaks before the problematic action.
|
|
|
|
|
I have a problem on how to link a CDialog with CLsitView in SDI application in mfc appwizard[exe] because I cannot use a DoModal function to link those pages.
|
|
|
|
|
Create the CDialog as a modeless child of the CListView then.
|
|
|
|
|
i wanna put a pic as my chat window background its in my resource
plz help
|
|
|
|
|
Ehh ?
What chat window ? Are you creating a chat program that has a received/sent text window, and you want to place a picture into the background ?
In that case, create a CBitmap variable, use CBitmap::LoadBitmap to load the bitmap from the resource. Then, during the WM_PAINT message of your window, use bitmap blitting (CDC:BitBlt ) to display the bitmap.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Hi, I've got this problem when developing my first DLL:
I have a DLL with an Interface class. I also have an application that calls some functions from the Interface class.
In the application there exist a function that I want to be called from the DLL (as a callback), so I pass a function pointer to the DLL.
I want to store the function pointer inside the DLL so I can call the function whenever I want, for this reason I have created an struct in which I store the function pointer and some other things. Until here, everything fine...
The problem comes when doing an instance of the struct; if I do that instance inside the Interface class (as a member) I cannot copy the function pointer in it; but if I do the instance outside any class (that is as "global") then there is no problem when copying the functon pointer.
Does anybody knows why can this happen?, it can be a problem of memory access?
Here is a "meta-language" example:
DLL:
In Interface.h:
typedef struct
{
functionpointer
}MyStruct;
class Interface
{
Interface ();
MyStruct mystruct;
void FillStruct (function_pointer_from_outside); //this is the exported function
}
In Interface.cpp
void Interface::FillStruct(function_pointer_from_outside)
{
mystruct.functionpointer = function_pointer_from_outside; //THIS GIVES EXECUTION PROBLEM
}
On the other hand if I make something like this, it works:
In Interface.h:
typedef struct
{
functionpointer
}MyStruct;
class Interface
{
Interface ();
void FillStruct (function_pointer_from_outside);
}
In Interface.cpp
MyStruct mystruct; //Instance as "global"!!!!!
void Interface::FillStruct(function_pointer_from_outside)
{
mystruct.functionpointer = function_pointer_from_outside; //OK!!!
}
HELP!!
|
|
|
|
|
My first question would be, what is the error during execution ? A run-time error ? An exception ? An access violation ?
Finding out the error type is integral to determining what the cause of the error is. I believe it to be an access violation, though. As a suggestion, you should try defining the function pointer as a standard pointer-to-function type. You shouldn't encapsulate it into a struct (what is the reason behind this, by the way ?)
Another working way could be to call GetModuleHandle on the main application. This returns a handle to the executable used to start the process. In english, it is the starting address of your main application. Now, if you pass this module handle into the DLL, you can use GetProcAddress inside the DLL code to query for the address of the function in the main module. This is something of a reverse-usage of the most common case: querying for a function address inside a DLL. Instead, we query for a function address inside the main application.
The returned value can then be used to invoke the function in the main application module. Using GetProcAddress ensures that the memory location pointed to by the returned pointer is ensured to contain information of to what module's memory area it points to. This may not be the case if you just pass the pointer using address-of operator.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
It is an exception error; a windows called "Just-In-Time Debugging" appear saying:
"An exception 'System.NullReferenceException' has occurred in testUI.exe".
Here is the definition of the pointer in the application (testUI.exe); as you can see, it is a pointer to a member function:
typedef void (CListener::*ListPtr)();
ListPtr pListPtr = new ListPtr;
pListPtr = &CListener::MyFunction;
I use a struct in the DLL because I want to store the pointer to the function, the pointer to the CListener class created in the textUI.exe, and an integer that acts as an identifier. Furthermore, I want to create an array of this struct, because I want the DLL to be capable to work with more that one textUI.exe at the same time (each one of them has its own version of "MyFunction"), and I want to store independently a reference to every function of each CListener object of each textUI.exe.
Thanks for your help
Irene
|
|
|
|
|
Humm..
It seems here that each textUI.exe executable creates a new object of the CListener class ? Is this correct ?
So, could there be a reason why you wouldn't just pass around a pointer to the object itself ? Like, the executable that loads the DLL provides a function that will return the address of the local CListener object ? If the DLL is aware of the declaration of CListener , you can use the returned address as a standard pointer-to-class to call the member functions.
This way, you wouldn't need a pointer to the member function, but would have a pointer to the entire class. The pointer's size wouldn't change much, so the memory requirements would be held in check.
Naturally, this approach would place more strict design issues on the DLL code, especially if different functions of the class need to be called at different times. Perhaps you should increase the struct so that in addition to the pointer and the reference number, it would contain a flag that specifies the function to call ?
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Yes, that is right, each textUI.exe creates a new object of CListener; the I create a pointer to the object: pListener.
At the beginning I tryed just to pass the pointer to the DLL, and to execute the function like this:
pListener->MyFunction();
but as CListener is also defined inside the DLL and an object instanstiated; instead of executing the MyFunction from the object outside the DLL, it was the MyFunction from the object inside the DLL the one that was executed... Strange, I know.
I read information in Internet, and I saw that always when you want to call a function from a DLL (and this function is outside the DLL), it was necessary to pass the pointer to the function. I did that and it worked, but with the constraint that I mention in the first post...
|
|
|
|
|
IrenePwr wrote:
- but as CListener is also defined inside the DLL and an object instanstiated; instead of executing the MyFunction from the object outside the DLL, it was the MyFunction from the object inside the DLL the one that was executed... Strange, I know.
This is correct. The DLL has it's own memory space, and the run-time interpreted the pointer you passed. Because a similar object was found in this local space, the run-time thought that it must be this one.
I also doubt that you did not use GetProcAddress to get either the address or the function to return the address. Try doing it so that you export a function from the main module, and use GetProcAddress to get this function. The function just returns the address of the local CListener object. This ensures that the function executes in the address space of the main module, and thus the address returned points into the main module's memory area instead of the DLL's.
One more option would be to try to use __declspec(dllexport) on the class in the main module. This WILL limit the number of the objects instantated to a single one, because you can't export multiple objects with same signatures. This wouldn't be safe. Then using __declspec(dllimport) to create a pointer-to-class in the DLL, and it "should" discover the correct class, as it looks for it across the DLL boundaries.
Greatest problems arise due to the CListener class found inside the DLL. Could it be a viable option to create a copy of CListener class and rename it as CDLLListener , for example ?
This would change the signatures of the objects, and might thus allow us to use the pointers you mentioned without the danger that it'd point to the local object instead of the remote one.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
This getting interestingly strange.
I did a few prelimenary checks of my own, and found out that if your main executable module and the DLL have similar objects declared, then using GetProcAddress will fail, if the methods of the classes are not declared as virtual.
I had a class called CMyDLLClass , and the same header file was contained in the DLL as well. Now, both the main module and the DLL created objects of this type. When the methods of the class were all declared as virtual, the run-time interpreted the pointers correctly. If they were not virtual, then calling the members through the pointer in the main module ALWAYS called the methods of the object declared in the main module's context, regardless of which pointer I used. More interestingly, the pointers pointed to different locations in memory as well...
This starts to feel like a bug in the compiler or the optimizations it uses. Not sure yet, though..
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Whow!!
That can be what happens in my project also... I don´t have the functions in the header file inside the DLL declared as virtual.
I will check it tomorrow and I'll let you know...
Now I don't have the project in front of me anymore (it is at work )
Thanks for your help and interest
Irene
|
|
|
|
|
Hi,
Yes, it was that. If I define my functions inside the DLL as virtual, then the run-time interprets the pointers correctly.
Anyway, I find the same problem as before... just try to store the pointer of your class CMyDLLClass that you pass to your DLL, in a variable that is declared inside another class from your DLL... I cannot do that. I can only store the pointer if the variable is declared globally (outside any class)...
In any case, the code looks much better now, though...
Irene
|
|
|
|
|
Hello,
I'm trying to use the CopyFile function on my XP Pro computer but it keeps returning 5 (a.k.a. ERROR_ACCCESS_DENIED). What do I need to do to make it copy? Do I need to mess with tokens? If so which one?
wWw.KruncherInc.cOm - My cool programs
|
|
|
|
|
|