I have a TCL application that is intented to run on Windows only and uses twapi to access some Windows-specific functions.
Now I need to call some C function that are in a custom DLL.
I know I can load the DLL with twapi::load_library (should be the same as LoadLibraryEx()) but I can't understand how to call a function within the DLL itself!
What did I miss?
I would prefer to avoid other dependencies (like critcl, for example) and to avoid to have to transform the current dll in a tcl extension (e.g. via SWIG) so a twapi only solution would be really helpful!
TWAPI doesn't seem to provide any public binding of GetProcAddress (the Windows API function for getting from the name to the address of a function in a DLL).
Use ffidl for simple APIs (i.e., where there are no callbacks) or critcl (for all kinds of APIs, including those with callbacks, because it can do much more extensive code generation; more effort to use though).
twapi's load_library command is there for manipulating the resources in a dll (string tables, icon etc.). It's not intended for calling functions in the dll since that, as Donal points out, requires marshalling and some code generation.
Looks like you'll have to use ffidl to do the job.
Related
I want to call functions defined by caller of a dll from dll. I am working on a C/C++ application. Main application may or may not use certain dlls as per the configuration provided and both the sides(Main application and dll) need to invoke each others functions. These example explained fairly well how one can create a dll and call it's functions at runtime.
https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=vs-2019
https://learn.microsoft.com/en-us/cpp/build/linking-an-executable-to-a-dll?view=vs-2019
However it doesn't explain how can I call functions defined in Main application from dll.
When I try to declare the same function in dll's headers it throws error saying failed to find function.
How can I tell to linker that certain function will be available at run time. In gcc there is --export-dynamic. This can be used for exporting the symbols and later shared object is able to use these symbols. Is there something similar in windows?
Edit:
Following discussion gives a possible solution, Here caller must pass the function to dll as argument.
How to call a function defined in my exe inside my DLL?
This will be little cumbersome to use in my situation. I am trying to port here a linux application on windows. There are many methods which are called by dll. Passing all of them to dll as function doesn't sound as a good idea however this can be doable as last resort. Other downside I see on taking this approach is, this will require Main application to be changed on every time plug in(dll) wish to use some new function of Main application.
I'm currently having some trouble with a VB6 application that needs to encode some text using the same encoding method available at .NET framework 4.5.
I've searched through the internet and found some functions that tries to do the encoding based in UTF-8, but it still doesn't match the 4.5 output.
Then I looked for a way to import the 4.5 framework DLL within the VB6 project. This is what I accomplished so far:
Private Declare Function dotNetUrlEncode Lib "System.Web.dll" Alias "UrlEncode" (str As String) As String
The problem is that the method "UrlEncode" it's inside the namespace "HttpUtility", "System.Web.HttpUtility.UrlEncode" and using the code above I cant access the method. I've tried changing it to look like the code below, but the problem persists, I cant reach the method UrlEncode:
Private Declare Function dotNetUrlEncode Lib "System.Web.dll" Alias "HttpUtility.UrlEncode" (str As String) As String
Private Declare Function dotNetUrlEncode Lib "System.Web.HttpUtility.dll" Alias "UrlEncode" (str As String) As String
Is there a way to reach the method UrlEncode inside "System.Web.dll"? Where am I going wrong?
Thanks for the help!
Best regards.
This will not work. The .NET DLLs contained managed code, which requires the .NET runtime. Your VB6 app can't call that code. Its process does not have the .NET runtime loaded.
You can only import functions from native DLLs this way. That's why it works for system DLLs included with the operating system.
The best solution would really be to consult the documentation and determine precisely how the UrlEncode function works. The internals of the implementation will not be documented, of course, but that doesn't matter. All you're interested in is the specification. Follow that same specification when implementing your own function if you cannot find a system function that has equivalent behavior.
If you absolutely needed to call .NET functions from a VB 6 application, it can be done. You will need to create a .NET wrapper that calls the framework-provided function and exposes in a COM-compatible manner using the ComVisibleAttribute. More information here, here, and here.
Is it possible to use js-ctypes to call a Windows DLL and have it return a nsISupports instance?
The Windows DLL does XPCOMGlue, but by not needing NSModule I hope I can improve the registration process.
I was hoping there was a ctypes.nsISupports type defined to use as return value, so if it's possible, how do I declare the call?
From my reading and experimentation, no, it doesn't look like you can. However, you could do the next best thing.
1. Create a win32 DLL exporting plain "C" symbols.
2. Create a "wrapper" XPCom component using JavaScript.
http://kb.mozillazine.org/Implementing_XPCOM_components_in_JavaScript
3. Plumb each plain "C" function exported by the DLL into the JavaScript object.
Possible improvement: create a generic JavaScript shim that does the plumbing automatically.
I have a DLL used in a compliance scenario (the details of which are irrelevant). The important point is that the main executeable must display the DLL version number. My solution was that the DLL has a function to return it's own version - ie obtain it from the its own version resource and return it as a string.
My reviewer says that the main program should work out the DLL version number. He even gave me some code to get the DLL module handle and extract the version using that.
My question is, which is a better design and why? My feeling is that, using OO principles, I should ask the DLL for its version number. Doing it the other way means that the main program needs to know how the version information is stored and is hence more tightly coupled to the implementation.
Note that I know exactly how to extract the version information from a DLL. My question is about the best place for the code that does this.
Can you clarify the environment that you're working in? For now, since you've already mentioned getting the module handle, I'll assume you're using C++ and calling one of a handful of Win32 functions (GetModuleHandle, LoadLibrary etc).
First of all, I'd be careful about applying OO principles in too wide a context. The object oriented paradigm helps you structure your software in a more maintainable and understandable way, the problem you're describing sounds like it maybe stretches outside of the boundaries of your application. If you want to get information about a separate resource, such as a DLL, you should consider using a standard approach to achieving this to ensure that your code is decoupled from the items that it needs to inspect.
If you introduce a function into the DLL to return the version number to your main application, you have created a tight coupling between your main application and any DLL that needs to supply it's version information (by essentially defining a bespoke API or interface for this).
You should consider using standard, platform-wide functionality to retrieve the information instead This will allow your application to version any DLL for which it can obtain a handle.
Assuming you have an HMODULE for the dll (and you're using C++), call the following functions to get the version...
GetModuleFileNameEx (to get the full path and filename of the DLL if you don't already know this)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683198(v=vs.85).aspx
using this filename, call
GetFileVersionInfoSize (look these up on MSDN)
This will tell you some crucial information about the file's version metadata (how much info, if any the file has). Assuming this function succeeds, call
GetFileVersionInfo
This will load all the file info metadata into a buffer, then call
VerQueryValue
Supply '\' as the lpSubBlock parameter to get the standard file info metadata (including the version number)
The above functions will allow you to write code to get the version number of any module that your code can get a handle to.
Of course, if you're using C# the solution is much simpler. Hope this helps...
When one should implicitly or explicitly link to a DLL and what are common practices or pitfalls?
It is fairly rare to explicitly link a DLL. Mostly because it is painful and error prone. You need to write a function pointer declaration for the exported function and get the LoadLibrary + GetProcAddress + FreeLibrary code right. You'd do so only if you need a runtime dependency on a plug-in style DLL or want to select from a set of DLLs based on configuration. Or to deal with versioning, an API function that's only available on later versions of Windows for example. Explicit linking is the default for COM and .NET DLLs.
More background info in this MSDN Library article.
I'm assuming you refer to linking using a .lib vs loading a DLL dynamically using LoadLibrary().
Loading a DLL statically by linking to its .lib is generally safer. The linking stage checks that all the entry points exist in compile time and there is no chance you'll load a DLL that doesn't have the function you're expecting. It is also easier not to have to use GetProcAddress().
So generally you should use dynamic loading only when it is absolutely required.
I agree with other who answered you already (Hans Passant and shoosh). I want add only two things:
1) One common scenario when you have to use LoadLibrary and GetProcAddress is the following: you want use some new API existing in new versions of Windows only, but the API are not critical in your application. So you test with LoadLibrary and GetProcAddress whether the function which you need exist, and use it in the case. What your program do if the functions not exist depend total from your implementation.
2) There are one important options which you not included in your question: delayed loading of DLLs. In this case the operating system will load the DLL when one of its functions is called and not at the application start. It allows to use import libraries (.lib files) in some scenarios where explicitly linking should be used at the first look. Moreover it improve the startup time of the applications and are wide used by Windows itself. So the way is also recommended.