Click here to Skip to main content
15,883,901 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I had a general question, I'm wondering if I were to create a dll in another language (such as c/c++ for example, as those are what I'm familiar with) that ran an infinite loop and call it from a vb.net program how would I go about ending that infinite loop. To clarify, I would press a button on my vb program that would run this c dll, and in the c dll a function would be called that ran off of an infinite loop, while(1) let's say, my question is how would the vb program stop the c program?


Overall, and most significantly, my question is can I make a button/code in vb that will open and close a dll when it is pressed--rather than having the dll stay in use?


Edit: Also, if there are any resources on how to do this, tutorials, walkthroughs, etc. I would highly appreciate a link to them. I've found some stuff, but it's a bit cryptic to read through and in many cases not helpful.


Relevant info: OS: Windows 7 (64 bit), programming in code::blocks with mingw compiler for c/c++, and vb.net in visual studio 2008


To further elaborate on my question, what I want is a c program to indefinitely read from a file (the file is constantly filling) and a vb program to start and stop the process. Also, the data is supposed to be sent by an array from the c dll to the vb application so that the vb application can store and use the data as well.
Posted
Updated 19-Jun-13 5:52am
v4
Comments
Sergey Alexandrovich Kryukov 19-Jun-13 8:23am    
It all strongly depends on what is that "DLL": is it a native (unmanaged) dll or another .NET assembly (and then it could be created with C++/CLI).
—SA

The only way I know how to do it is to run the function on a separate thread, and then terminate the thread when you are done.

Look up threading and interop on google. .NET can generate interop assemblies for you in most cases.

Interop In .NET[^]
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 19-Jun-13 8:45am    
You did not explain how to do it, and this is not a trivial thing. Second part of the question is also far from trivial.
Please see my answer.
(I did not vote this time.)
—SA
The scenario with the thread should be explained in more detail: you have to use such an non-trivial tool as System.Threading.Thread.Abort:
http://msdn.microsoft.com/en-us/library/system.threading.thread.abort.aspx[^].

In contrast to some common believe, it does not terminate thread. It performs such a non-trivial operation as exception seeding into the target thread. The exception is System.Threading.ThreadAbortException, you can handle it to perform some last clean-up action, the "last will" of the thread:
http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx[^].

In general case, if can be dangerous. You should use such things only if you understand very well what you are doing. But: if the code is hanging, it may means that it is already bad enough, so you simply don't have a better remedy in this situation.

Now, about loading and unloading. This is a complex matter which I would advise not to get into, unless you have extremely good understanding of technology. The kind of DLL makes dramatic difference.

If this is a native (unmanaged) DLL, you normally use it via P/Invoke:
http://en.wikipedia.org/wiki/P/Invoke[^],
http://msdn.microsoft.com/library/en-us/vcmxspec/html/vcmg_PlatformInvocationServices.asp[^].

This CodeProject article could also be helpful: http://www.codeproject.com/csharp/EssentialPInvoke.asp[^].

If you invoke some methods in you DLL, you won't be able to load or unload it. (Again, you did not explain any reasons for doing it, so I would warn you against it.) If you really want to load and unload it, you would rather invoke Windows API methods and use them:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175%28v=vs.85%29.aspx[^],
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179%28v=vs.85%29.aspx[^],
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212%28v=vs.85%29.aspx[^],
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683152%28v=vs.85%29.aspx[^].

Now, about a .NET assembly. Normally, you just reference and use it. But can you load or unload it. Surprise: you are not allowed to unload a .NET assembly from memory, as it would be unsafe, not acceptable for memory-managed system — what if some code keeps access to some methods/properties of already unloaded code?

You can only unload the .NET assembly if it was loaded in some separate Application Domain. In this case, what you could do is to unload the whole Application Domain. But how to use the assembly if it is in a separate Application Domain? This is tricky.

If you want further detail, please see my past answers on this topic:
Create WPF Application that uses Reloadable Plugins...[^],
AppDomain refuses to load an assembly[^],
code generating using CodeDom[^].

—SA
 
Share this answer
 
v4
First, you don't have two different programs. The .DLL code is loaded into the address space of your VB.NET app. It becomes parts of your code.

If you start the inifinite loop on the startup thread of the app, then the loop will have complete control and your VB.NET code will not get anychance at all to run, so you can't stop the loop.

The way around this is to use any available threading methods in VB.NET, such a running the C method in a Thread or using a BackgroundWorker component. The problem with this is that you would have to modify the C code to look for some kind o bailout flag your VB.NET code sets to tell it to end itself gracefully. Don't use Thread.Abort. That's the very messy way to kill a thread, not shut it down gracefully.

Google for "VB.NET BackgroundWorker" for lots of examples.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 19-Jun-13 8:54am    
Sorry, but in the situation described by OP Thread.Abort is the last resort. Please read it carefully: there is no a graceful exit at all, in this particular case.

The danger of Abort is discussable, but many opponents don't have a clue and think this is something like TerminateThread, but it is not, not even close. When used with care, it can be used in a fully safe way (but of course, not in the case of some arbitrary code executed in the thread).

It would be safer to say that it should be used with care. As the general case is really unsafe, you can consider is as "better then nothing": the user can use such Abort and then do at least something, work just a bit more to complete important things, tolerating adverse effects of abortion of some code which provides no ways to clean up after abort. After all it may lead some resource leak, unclosed file handles, etc. But remember that the only alternative would be the termination of the whole process, which is of course much safer, but may mean the total loss of the user's current work. Abort is much better remedy in this case.

—SA
Dave Kreskowiak 19-Jun-13 9:40am    
I said don't use Abort because of the assumption that it's an unmanaged code DLL. It's a bad practice to begin with. If you have the choice, as he apparently does as he said if "he creates a DLL", then he should provide a gracefully exit, not a messy one. We have no idea what his "infinite loop" code does, so he could just as easily orphan resources with Abort. Better to take the safer route.
Dave Kreskowiak 19-Jun-13 12:52pm    
OK, who voted me a 1??

Granted, I didn't go into the post you did, but still, compared to Solution 4!! Come on!!

No, I'm not saying it was you SAK!
Solution

The most simple way of ending a program will be to have a text or xml file, in which you can save the value of 1 or 0. If you want to end the program then simply save the value of 0 in that text file, which your function in Dll should detect and End the program. In this way there will be no side effects and the program will end graceously.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900