Is it possible to start (and stop) a stream inside a DLL?

I am reflecting on some ideas for creating a DLL for some of the common things that I do. One thing I would like to check if possible is to start the thread inside the DLL. I am sure that I can at least start it, and automatically release it at the end (and force it to decisively cease its “I”), which I see will not be a problem. But as soon as I start, I don’t see how I can continue to communicate with him (especially to stop him), mainly because every DLL call is unique (as far as I know), but I also know very little about the subject.

I saw how in some cases DLLs can be loaded at the beginning and released at the end when it is no longer needed. I have 0 knowledge or experience with this method, except as soon as I see something related to it, I can’t even tell you what and how, I don’t remember. But is it possible?

I know about ActiveX / COM, but this is not what I want - I would like only a basic DLL that can be used in different languages ​​(in particular, in C #).

Also, if possible, how will I make callbacks from the DLL to the application? For example, when I start a thread, I will most likely assign a function (which is located inside the EXE) as an event handler (which are launched from the DLL).

So, I guess I am asking: how to load the DLL for continuous operation and release it when I have finished - as opposed to the simple method of calling individual functions in the DLL as needed. In the same case - I could assign variables or create objects inside a DLL. How can I assure that as soon as I assign this variable (or create an object), how can I make sure that the variable or object will still be available the next time the DLL is called? Obviously, this will require a DLL initialization / termination mechanism (IE create objects inside a DLL when loading a DLL and free objects when unloading a DLL).

EDIT: In the end, I will wrap the DLL inside the component, so when the component is instantiated, the DLL is loaded and the corresponding stream inside the DLL is created, when the component is free, the DLL is unloaded. You also need to make sure that if there are, for example, 2 of these components, then there will be two instances of the DLL loaded for each component.

Does this have anything to do with using IInterface? Because I also have 0 experience with this.

No need to answer it directly using the sample source code - a link to a good tutorial will be great.

+4
source share
4 answers

The main template you are looking for is as follows:

  • EXE calls the function in the DLL.
  • EXE passes parameters as needed.
  • The DLL does the work, starts the thread, returns a handle. And by the handle, I mean in the free sense of work, and not in the Windows descriptor.
  • Now the EXE can interact with the DLL, calling more functions, passing a descriptor.
  • A DLL can communicate with an EXE, for example. on callbacks if the EXE provided callbacks.
  • When it is time to stop, the EXE calls the DLL function, passing the handle. At the moment, the DLL is picking up.

Behind the handle is any state that the DLL should track between calls. From an EXE point of view, this handle is opaque.

This type of template may work fine even when using languages ​​other than OOP, such as C. However, it is much easier to use OOP objects. Since you want to cross module boundaries, you will be much safer to use interfaces rather than Delphi objects. If you pass Delphi objects across module boundaries, you can transfer only part of the object data, but not part of the code.

When using interfaces, the interface variable returned by the DLL functions as a descriptor in my numbered list above. It contains any instance data. Using interfaces provides readiness for expansion.

As for part of the stream, you should use a higher level stream library, not raw streams. The library I would recommend is Primož Gabrijelčič OmniThreadLibrary .

Regarding your editing:

I will wrap the DLL inside the component, so when the component instance is created, the DLL will be loaded, and the corresponding DLL will be created inside the DLL, and then when the component is free, the DLL will be unloaded. You also need to make sure that if there are, for example, 2 of these components, then there will be two instances of the DLL loaded for each component.

When loading a DLL into a process, there is only one instance. In particular, if you intend to use global variables, there will be only one instance of each global variable, no matter how many times you call LoadLibrary .

+7
source

I tried to post it as a comment, but it ran out of characters: the short answer is yes, it should be possible. Designing an API so that it is synchronized and works well is another story. I usually end up in a box for TCP / IP networks for cross-platform / language communication, but especially in an environment where you are looking for asynchronous operations. It would be difficult to design a service that has Start, Stop and isReady.

http://docwiki.embarcadero.com/VCL/en/Classes.TThread

You are immersed in a territory that will allow you to use the conditions of the race and requires that some smart checks be effective. Just be aware of this and read on this topic.

Here's the basics of creating a DLL: http://delphi.about.com/od/windowsshellapi/a/dll_basics.htm

And here are the basics of its use. I have been away from Delphi for a couple of years, otherwise I would have weighed a quick example, I had no desire to buy a copy for myself, but the principles are the same in all languages. It will load a Java / C # tutorial on streaming design and interface.

Generally speaking, a “simple” installation can be:

Class - Object WorkToBeDone - boolean isRunning - boolean isReady - procedure stop; - beginning of the procedure (work); - function isReady (): boolean;

Your thread will work in the while loop of the structure:

 procedure start(work) //inside new thread begin isRunning := true; isReady := false; while(isRunning) begin doIncrementalOperationOnWork(); thread.yield; end; work := thread.getWork(); isRunning := false; isReady := true; end; 

His rough sketch, but the idea is that the outside caller can check if he is ready and when he returns. I'm not sure what you are doing, but this is a "possible" solution. This is just a lot, and, according to Delphi, 16 threads per processor - this is their "upper" limit. Just keep in mind the limitations. Other people may have better suggestions, this is just an abstract template that I use to offload to threads that seem simple and straightforward.

+2
source

A lot of questions and days of fun training.

Loading and unloading dlls is not complicated, you add a function called dllMain. This is a special guy who uses windows to access loading and unloading DLLs. More here

About Delphi

Many articles on delphi and threading, as well as how to use interfaces in delphi.

When you have any more specific questions, I can help. However, as a Delphi and C # programmer, I would write this material in C #, wrapping it for Com, and then calling it from Delphi. You will get much more help, find more tutorials, and language support, especially in complex scenarios, will be better.

BackgroundWorker and threading, not to mention parallel extensions, make .net threads fun. In Delphi, it just hurts.

+1
source

There are threads in the PROCESS.

The process launches executable code: either the code embedded in the .exe or the code downloaded from the external .dll.

A process can also run code “remotely” - code in a separate process or even a separate machine - with technologies such as DCOM (Microsoft COM / ActiveX), WCF (Microsoft.Net), RMI (Java) or CORBA / IIOP (among others) .

Since you posted on a forum in Delphi, the best option might be to research Delphi Prism:

http://edn.embarcadero.com/article/41598

If you're stuck with an older version of Delphi 7, the best option would be to just use raw sockets to communicate with remote PCs.

0
source

Source: https://habr.com/ru/post/1383144/


All Articles