|
You can just copy the .dll's that you want but you have to put them into directories with their manifests. For example, (from here[^])
to include Microsoft.VC80.MFC.dll you need to copy the \Microsoft.VC80.MFC directory from %VCINSTALLDIR%\redist\ into the loacl application directory like:
<br />
\bin\<br />
myApplication.exe<br />
\Microsoft.VC80.MFC<br />
This works on XP but I don't think it works on earlier OSs. A simple way to install is to create a setup project in VS2005.
Peter
"Until the invention of the computer, the machine gun was the device that enabled humans to make the most mistakes in the smallest amount of time."
|
|
|
|
|
Hi,
What do I need to do so that the CRuntimeClass addresses known to my Regular DLL correspond to the CRuntimeClass addresses known to a CObject-derived object passed to the DLL from an application?
Here's the details of my problem (forgive the verbosity)...
I needed to control access to an object used by multiple threads. I used the Microsoft-documented CMutex/CSingleLock approach. Here's what my object class sort of looks like:
class MyThreadSafeResource
{
public:
MyThreadSafeResource(CString dllFileName);
void start();
void someMethod();
private:
static UINT run(LPVOID p);
CMutex m_lock;
HINSTANCE m_dll;
};
MyThreadSafeResource::MyThreadSafeResource(CString dllFileName)
{
// Load the passed DLL.
m_dll = ::LoadLibrary(dllFileName);
}
void MyThreadSafeResource::start()
{
CSingleLock singleLock(&m_lock);
singleLock.Lock();
// Spawn a worker thread
::AfxBeginThread(run, this);
}
void MyThreadSafeResource::someMethod()
{
CSingleLock singleLock(&m_lock); // POINT X
singleLock.Lock();
...
}
UINT MyThreadSafeResource::run(LPVOID)
{
MyThreadSafeResource* resource = (MyThreadSafeResource*)p;
// Call the function exposed by the DLL.
typedef void (*ExternalFunction)(LPVOID p);
ExternalFunction dllFunc = (ExternalFunction)::GetProcAddress(m_dll, "dllFunc");
dllFunc(resource);
return 0;
}
Here's what my exported DLL function sort of looks like:
extern "C"
{
__declspec(dllexport) bool dllFunc(LPVOID p)
{
MyThreadSafeResource* resource = (MyThreadSafeResource*)p;
resource->someMethod();
...
}
}
From my application's main thread I create a new instance of my resource class and "start" it:
MyThreadSafeResource resource = new MyThreadSafeResource("C:\TEMP\MYDLL.DLL");
resource->start();
At first, everything goes well... my resource object loads the DLL successfully, in the "start" method my worker thread is created successfully, my object is passed to the worker thread successfully, the worker thread calls the function within my DLL successfully, my object is passed to the DLL function successfully.
Its when the DLL function calls a method in my passed object that things go bad. My application abends at "POINT X" with the following message:
Unhandled exception at 0x00643185 in MyApplication.exe: 0xC0000005:
Access violation reading location 0x00c85edc.
It appears that the called method's CSingleLock construction is failing when it tries to ensure that the passed CMutex object is derived from CSyncObject. Here's the call stack at the time of failure:
MyDll.dll!CRuntimeClass::IsDerivedFrom(const CRuntimeClass * pBaseClass=0x101a1e9c) Line 174 C++
MyDll.dll!CObject::IsKindOf(const CRuntimeClass * pClass=0x101a1e9c) Line 45 C++
MyDll.dll!CSingleLock::CSingleLock(CSyncObject * pObject=0x00b87878, int bInitialLock=0) Line 90 + 0xd C++
MyDll.dll!MyThreadSafeResource::someMethod() Line 126 + 0x11 C++
MyDll.dll!dllFunc(void * p=0x00b87830) Line 52 + 0x8 C++
MyApplication.exe!MyThreadSafeResource::run(void * p=0x00b87830) Line 238 + 0x9 C++
MyApplication.exe!_AfxThreadEntry(void * pParam=0x0012f194) Line 114 + 0xd C++
MyApplication.exe!_threadstartex(void * ptd=0x00b87a58) Line 241 + 0xd C
kernel32.dll!7c80b683()
Any thoughts? Any and all help appreciated.
Thanks!
Peter
|
|
|
|
|
Are you sure the pointer (to the passed object) the DLL is using is valid?
If so, what does your DllMain() function look like?
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
I figured out my problem... me.
I just had to add the AFX_MANAGE_STATE macro at the beginning of the exported function in my DLL:
AFX_MANAGE_STATE(AfxGetStaticModuleState())
Just standard "DLL using MFC" stuff. It's obviously been way too long since I've worked with this stuff.
Peter
|
|
|
|
|
Cool
Extension DLL Hell!
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
hello everyone
I want to Find all computers in a network... But these computers are not in a group using network setup wizard...
IpEnum and xLanInfo doesn't work.
please help me.
Thank u
Every new thing you learn,Gives you a new personality.
|
|
|
|
|
Have you tried NetServerEnum() ?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
I'm writing a file manipulation program, and was wondering in your experience what is the most efficient buffer size to load at a time and manipulate. Would this simply be based on the largest chunk of memory I am willing to allocate on the system, or can smaller buffers produce faster results? Speed is important because I could be converting several thousand files at a time.
Thanks,
Dustin
|
|
|
|
|
How much overhead would it be to first iterate the list of files, look for the largest file, and allocate that much memory?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
The biggest problem would not neccesarily be the overhead, but the allocation itself. What happens if I run accross a 2GB file? I'm actually attemting to write an encryption program, more as an experiment than anything, and do not know the make up of the files I will be opening.
|
|
|
|
|
Dustin Henry wrote: What happens if I run accross a 2GB file?
Indeed that would be a problem.
Dustin Henry wrote: I'm actually attemting to write an encryption program...
What does the encryption algorithm require (in terms of input)?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
I am actually using my own random number generator to randomly convert each byte of data based on an initial seed, so the only requirement is that I process the data in order.
|
|
|
|
|
Then I don't see why you couldn't allocate a couple of megabytes for that.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
So basically the bigger the better then?
|
|
|
|
|
To a point, but you don't want to get so big that you introduce more disk thrashing. Allocating several MB of memory is not usually noticeable with semi-modern machines.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Great, thanks for your help David.
|
|
|
|
|
(I feel dumb this morning, really, really dumb; you have the right to giggle )
I'm trying to set the initial dir of a CFileDialog to an existing path.
if I do this it works; but the path is not hardcoded like that.
CString sInitialPath("c:\\max\\");
CFileDialog dlg( FALSE, NULL, "toto.ext");
dlg.GetOFN().lpstrInitialDir = sInitialDir;
The path is taken from an Edit Box.
CString sInitialPath;
m_EditBox.GetWindowText( sInitialPath );
CFileDialog dlg( FALSE, NULL, "toto.ext");
dlg.GetOFN().lpstrInitialDir = sInitialDir;
And this does not work because the string contains single backslash ( c:\max ) and letters will be "escaped" out of the string.
There must be a better way than manually add backslash to the string ?
Is there a default "cleanup" function that will do it ?
Thanks.
(again you can have a laugh.)
|
|
|
|
|
Off the top of my head you may want to try this:
sInitialPath.Replace(_T("\\"), _T("\\\\"));
Dustin
|
|
|
|
|
The above replacement make sense only whenever the string has to be read by the compiler.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
He wanted double slashes, I gave him double slashes. You don't actually expect me to consider the logic of my statements do you?;P
|
|
|
|
|
Dustin Henry wrote: You don't actually expect me to consider the logic of my statements do you?
ehm... No, of course!!!
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Maximilien wrote: CString sInitialPath;
m_EditBox.GetWindowText( sInitialPath );
CFileDialog dlg( FALSE, NULL, "toto.ext");
dlg.GetOFN().lpstrInitialDir = sInitialDir;
Uhm, there's a mistake in the last line, you should do instead
dlg.GetOFN().lpstrInitialDir = sInitialPath;</code>
BTW in the meanwhile I'm trying the code...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
As supposed, the following (yours, basically) code works fine on my system (dlg.m_ofn is there because I'm using VC6).
CString sInitialPath;
m_EditBox.GetWindowText( sInitialPath );
CFileDialog dlg( FALSE, NULL, "toto.ext");
dlg.m_ofn.lpstrInitialDir = sInitialPath;
dlg.DoModal();
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Maximilien wrote: ...the string contains single backslash ( c:\max ) and letters will be "escaped" out of the string.
This is only the case with string literals.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
that's strange, because escaping a backslash matters only in the source code... if the user enters in the edit box a path (which is for him compound of sigle slashes of course), that will behave as if you had written in your source code the path with '\\' characters...
and same in the debugger. it does display single slashes, but look at the ascii code of the characters, and you'll see that no way you need (and you musn't !!!) replace single slashes with double ones...
but i can't help you much, because i have no compiler with me at the moment...
|
|
|
|