How to solve the DLL function call problem - c++

i have couple of query's with respect to DLL,
1)If i load the DLL in run time, i guess DLL will be in separate thread right?
2)If i call a function present in DLL, and that function takes much time to return the value then how can i make my application thread to wait till the DLL's function return value.
How can i solve the second problem

Your assumption is incorrect.
If you load a DLL, and then call one of its functions, the call is made synchronously, just like any other function call.
There is absolutely no reason why the DLL should be loaded in another thread. You may do it, of course, but this is not the default.

1) No. The dll is just code. The code in the dll is called in the context of whatever threads you create. *
2) As a result, your application will wait for the dll's function to complete.
A Dll can create worker threads as a result of your application calling the dll. However, you cannot call directly into a thread. Any call your code makes will always happen synchronously on the current thread.

Are you using qt threads? Otherwise I cannot understand why you would use the "qt" tag.
As for your problems it seems to me that you have to create another thread which will call the function contained in the DLL.
When this thread exits than you can assume you have the function's result.

You can in switch implement DLL_THREAD_ATTACH too.
You must call this function from thread you want to slow down, or get Thread Suspend before function call, and Thread Resume after.

Related

Mutex sharing between DLL and application

I have an multithreaded application that uses a DLL that I created. There is a certain function that will fail if the DLL has not run a certain function yet. How can I make sure that the thread that runs this application function waits for that DLL function to complete before continuing?
Visualization:
O = DLL Function Completes
T = Application Function Starts
App Thread:--------------O----------------------------------
DLL Thread:----------------------T--------------------------
Several approaches:
First thought would be to put the code into DLLMain(), which is executed automatically on application/DLL load. Not everything can be done here though, like blocking operations or operations that require loading other DLLs. Be sure to read and understand the docs if you try this approach.
The second thought is to throw or assert(), so that the init function must be called before any other one, like WSAStartup(). You would then have to call this once in main() before creating any other threads. This is a simple approach. It requires manual work and you can't create threads inside the ctors of globals (which is always dangerous anyway), but at least it will tell you if you got it wrong and, assuming the assert() approach, has zero overhead for release builds.
A third variant is using Boost.Thread's One-time Initialization initialization, which seems to do what you want.
You could use a named event.
Create an event for both the app and DLL to share first:
HANDLE myEvent = CreateEvent(NULL, false, false, L"MyEvent");
To signal complete use:
SetEvent(myEvent);
To wait for completion use:
WaitForSingleObject(myEvent, INFINITE);

Threads disappeared on DLL ExitInstance

I have a windows DLL with functions InitInstance and ExitInstance.
The DLL creates some threads, worker threads with _beginthreadex and threads with Message Queue,
derived from CWinThread (MFC).
The DLL should useable by any application.
I wrote a small host application for this DLL to test and it worked fine, except
when i close this host application without calling FreeLibrary before. In this case, ExitInstance
is called as well, but all threads are disappeard, which is quite unusual and leads to a deadlock
as some routines waiting for a thread finished which does not exist any longer - as it was
finished or killed.
I need to go this way (skip to call FreeLibrary) in order to simulate what could hapen when
other applications use this DLL.
ExitInstance is called, but all threads which
normally still running are disappeared - most probably because DLL is handled somehow differently
when unloaded from host process if you do not call FreeLibrary before.
They disappear silently, for instance, if a thread just implements a loop with a WaitForSingleObject within loop, this thread is not finish normally.
thread()
{
while(running == true)
{
WaitForSingleObject(...);
}
threadfinished=true; /// 1
}
If calling FreeLibrary before closing application, code section 1 is called.
When closing application without calling FreeLibrary before, code section 1 is never called
but loop also not running any longer as thread was removed.
How should I handle this situation ? Thank you
The documentation for CWinThread::ExitInstance is very clear: "Do not call this member function from anywhere but within the Run member function." (i.e. CWinThread::Run, the thread itself).
Obviously, that means Windows is NOT going to call ExitInstance for you. Nor is the host application, since that has no idea about your threads.
What is called is DllMain, but only once and with argument DLL_PROCESS_DETACH. You won't get DLL_THREAD_DETACH because that happens after your threads exit cleanly (i.e. ExitInstance or returning from CWinThread::Run).
By the way, consider what code your threads could be running after your DLL has been unloaded. It can't be your functions or MFC, since those functions no longer exists. The thread would crash with an Access Violation because its instruction pointer now points to unallocated memory.

Calling a function from DLL, in an injected process

Is there a way to call a function, that resides in a dll, (the dll is injected into a process) from that process?
By this I mean if i have myDLL.dll that exports a function, lets say void f(){do sth} and a process myProcess, "myDLL.dll" is injected using CreateRemoteThread(), can I call f() from myProcess so actually myProcess is the "user" that initiated the call to this function ?
I need to do this because I want the function f() not to be dependent by a certain program that can be killed in Task Manager, since employes can find the process and kill it. My manager asked me to do this because he thinks employees are doing other things than work.
Just use the usual, LoadLibrary() and GetProcAddress()
What you want to do probably won't work, and isn't the right approach anyway. The correct solution for preventing users from killing a process can be found here.

How does one call into COM from worker thread created with NT's QueueUserWorkItem?

I've got a set of tasks that I slaved to the NT threadpool using QueueUserWorkItem. I need to make some calls to COM from these separate threads to access data inside WMI. I'm unsure, however, how the correct calls to CoInitializeEx need to be made.
Basically, the CoInitializeEx docs say that the call should be made once per thread. But I don't own these threads—NT does. I don't know when they get created or destroyed, or anything of that nature. Do I basically call ::CoInitializeEx() (with COINIT_MULTITHREADED) at the beginning of the thread routine, and then ::CoUninitialize() at the end of my thread routine?
You can call CoInit and CoUninit multiple nested times, they just have to be balanced. Your proposed solution of doing it at the beginning and end of your thread proc is reasonable. Just make sure you don't have any early exits that skip the CoUninit call, and don't call CoUninit if CoInit fails.

notify an object when a thread starts

i have an object A which should be notified (A::Notify() method) when some thread starts or dies.
Lets say this thread dynamically loads some DLL file of mine (i can write it).
I believe i should write the dllMain function of this DLL, however i'm not sure how to get a reference to the A object from this function so i can run it's Notify() method.
any ideas?
A DLL is loaded once in every process. Once loaded, its DllMain is automatically called whenever a thread is created in the process. Assuming A is a global variable, you can do the following:
After you first load the DLL, call an exported function that will set a global pointer to A in the DLL
Whenever DllMain is called with the reason being thread attached, call A via the pointer you have in the DLL.
Another option would be to start a message loop in your exe, and pass it's thread ID to the DLL. Then, whenever a thread attaches to the DLL send the message loop a message with the details of the created thread. This is a slightly more complicated solution, but it will save you the need of making the DLL familiar with the A class.
Is it okay to make A::Notify() as static method?
Otherwise, Singleton method might serve the purpose.
So if I understand you write, in your main program you have an instance of class A. When your main program loads certain dlls you want it to call A::Notify for that instance?
As far as I'm aware there is no way to pass an additional argument to LoadLibrary.
If A::Notify can be either static, or A is a singleton, export a "NotifyA" method from the exe, then have the dll call LoadLibrary("yourexe") and you GetProcAddress to get the address of NotifyA which you can then call. (Yes exe files can export methods like dlls!)
A second option is to write your own LoadLibrary, that call a second method after dll main, eg
HMODULE MyLoadLibrary(string dll, A *a)
{
HMODULE module = LoadLibrary(dll.c_str())
void (call*)(A*) = void (*)(A*)GetProcAddress(module, "Init");
call(a);
return module;
}
The dlls Init method can then store the A instance for later.