Recently I was trying to add unit tests to an existing binary by creating a extra (DLLMain) entry point to an application that already has a main entry point (it is a console exe). The application seemed to compile correctly although I was unable to use it as a DLL from my python unit test framework, all attempts to use the exe as a dll failed.
Has anyone any ideas or experience in adding extra application entry point with any input as to why this would or wouldn't work?
There are some problems which you should solve to implement what you want:
The exe must have relocation table (use linker switch /FIXED:NO)
The exe must exports at least one function - it's clear how to do this.
I recommend use DUMPBIN.EXE with no some switches (/headers, /exports and without switches) to examine the exe headers. You can compare the structure of your application with Winword.exe or outlook.exe which exports some functions.
If all this will not helps, I'll try to write a test EXE application which can be loaded as an exe and post the code here.
UPDATED: Just now verified my suggestion. It works. File Loadable.c looks like following
#include <windows.h>
#include <stdio.h>
EXTERN_C int __declspec(dllexport) WINAPI Sum (int x, int y);
EXTERN_C int __declspec(dllexport) WINAPI Sum (int x, int y)
{
return x + y;
}
int main()
{
printf ("2+3=%d\n", Sum(2,3));
}
The only important linker switch is /FIXED:NO which one can find in advanced part of linker settings. The program can run and produced the output "2+3=5".
Another EXE loaded the EXE as a DLL and calls Sum function:
#include <windows.h>
#include <stdio.h>
typedef int (WINAPI *PFN_SUM) (int x, int y);
int main()
{
HMODULE hModule = LoadLibrary (TEXT("C:\\Oleg\\ExeAsDll\\Loadable.exe"));
PFN_SUM fnSum = (PFN_SUM) GetProcAddress (hModule, "_Sum#8");
int res = fnSum (5,4);
printf ("5+4=%d\n", res);
return 0;
}
The program also can run and produced the output "5+4=9".
I don't know for sure, but I would guess that Windows simply refuses to load an EXE in-process and a DLL as a new process, plain and simple.
These questions appear to contain more detail:
Can the DllMain of an .exe be called?
DllMain in an exe?
The simplest way to get both behaviours in one executable image is to design it as a DLL, then use rundll32.exe to execute it standalone. There's no need to write your own wrapper.
Related
I'm not really sure if that is the actual name of what I mean, but you'll get it.
Supose I have 3 projects, 2 of them builds as libraries, and the other one as an executable. For my scenario I'll use MSVC++ and the libraries will be dynamic (DLLs), and of course executable .exe, but I also want to if static libraries are also included.
And please, if I'm wrong on any of my assumptions, please correct me.
In the first library project, FirstLib.h:
#pragma once
#include <SecondLib.h>
#ifdef DLLONE_BUILD
#define DLLONE_API __declspec(dllexport)
#else
#define DLLONE_API __declspec(dllimport)
#endif
int DLLONE_API MainOne();
int DLLONE_API InternalOne();
and FirstLib.cpp:
#include <FirstLib.h>
int MainOne() { return InternalTwo(); }
int InternalOne() { return 100; }
Similarly, in the first project, SecondLib.h:
#pragma once
#include <FirstLib.h>
#ifdef DLLTWO_BUILD
#define DLLTWO_API __declspec(dllexport)
#else
#define DLLTWO_API __declspec(dllimport)
#endif
int DLLTWO_API MainTwo();
int DLLTWO_API InternalTwo();
SecondLib.cpp:
#include <SecondLib.h>
int MainTwo() { return InternalOne(); }
int InternalTwo() { return 200; }
Finally, in the executable project, main.cpp:
#include <FirstLib.h>
#include <SecondLib.h>
int main() { return MainOne() + MainTwo(); }
So when compiling the two libraries, I obtain the two .dll files, and two .lib files. Each library must have the other library .lib to link.
Then, the executable must be linked with the two .lib, and when executed, .dll should be in a known path for the exe, be the same path or some PATH.
Now for the questions:
Is doing this a correct aproach, or should be avoided?
Exe needs the two dlls, but each dll needs the other dll. Does each dll loads the other one again, or uses the same loaded version from .exe?
If they were static libraries, would each library be loaded two times, or just one? Or none of them?
And if you have a good resource where I can find more about this, it will be really apreciated.
Thanks in advance!
UPDATE as why would I do this : Imagine creating an engine.
I have (just to be consistent with the previous scenario) a library called Kernel, and a library called System. Also a binary project.
Kernel has the code regarding program execution (main loop), handling, base clases and other high level things.
System has the code regarding HAL and low level code. OpenGL things, file IO things, etc.
Binary has the main function, and program specific implementation of the engine.
Why do I need that cross-linking:
Kernel in Binary: main() (Binary) calls Kernel.Initialize() (Kernel).
System in Binary: CreateActor()(Binary) calls System.OpenGl.MeshCreate() (System)
System in Kernel: Kernel.Initialize()(Kernel) Initializes the Kernel, but also the System by calling System.Initialize()(System).
Kernel in System: class System(System) inherits from class Object(Kernel)
I know i could avoid this circular dependency by, say, Initializing System from binary calling System.Initialize()after Kernel.Initialize().
But then, Kernel will depend on no one, System would depend on Kernel, and Binary on both Kernel and System.
So my question remains in this case too
Is removing the cross dependency but to have this scheme a better aproach?
Same as question two: Does Binary and System both depending on Kernel as well asBinary in System represents double code, double loading or a performance or size downgrade or some kind of undesirable effect?
I have a 32-bit 3rd party C DLL that I need to integrate with, but am hitting an error that's difficult to understand/track down.
I can compile and successfully link a simple C++ 32-bit app consisting of the following:
#include "stdafx.h"
#include <windows.h>
extern "C" int __stdcall external_method(int cardno);
int main()
{
int n = external_method(0);
return 0;
}
When I try to run the app though in debug mode it gives the following:
Unhandled exception at 0x100AADF5 (ExternalModule.dll) in
ConsoleApplication2.exe: 0xC0000005: Access violation reading location 0x00000000.
However, if I create a simple C# application that uses DllImport/PInvoke to call the same function it runs fine:
namespace ConsoleApplication3
{
class Program
{
[DllImport("ExternalModule.dll")]
public static extern int external_method(int n);
static void Main(string[] args)
{
external_method(0);
Debug.WriteLine("YES!");
}
}
}
I'm struggling to understand how one can work and the other fail. Unfortunately I have no access to the developer of the C DLL.
Any help much appreciated.
Update Thanks for the comments. Here is the header file entry for the method:
int __stdcall exernal_method(int cardno);
Am reasonably sure that the calling convention is ok. The DLL is being loaded because using the debug version of the DLL I can see it output some messages to the debug output before it fails.
Could it be an issue with stack being corrupted on exit of the method? I tried a couple of different calling conventions but this is the only one that the linker was able to work with.
Stack corruption is unlikely.
One possible reason is different DLL loading method. Your C++ app loads it statically (Windows loads your DLL before the process launched), C# dynamically (CLR loads the DLL after the process started to run). To test this hypothesis, remove ExternalModule.lib from linker, change your C++ code to call LoadLibrary and GetProcAddress instead.
Another possible reason is C# runtime initializes COM, C++ app doesn’t, and your DLL tried to use COM. In your C++ app, try to add CoInitialize[Ex] before your exernal_method.
I have 2 VS projects in separate solutions. First one a dll, and the second one an xll trying to call a function from the first one. While it compiles without errors, Excel says
"The file you are trying to open, 'test.xll', is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now?"
and if I press yes, I see a bunch of chinese-like letters. If I don't call the function from the dll project, then the xll works properly. What am I doing wrong? Using VS2010 and Excel 2010 x86.
The first one is a dll project
square.cpp
double _stdcall square (double &x) {
return x * x;
}
square.h
#pragma once
__declspec(dllexport) double _stdcall square (double &x);
The second project is an xll project
static AddIn xai_exp(
"?xll_exp", XLL_DOUBLE XLL_DOUBLE,
"XLL.EXP", "Number"
);
double WINAPI xll_exp(double number) {
#pragma XLLEXPORT
return square(number);
}
I also made a defFile for when I tested with VBA, but I don't think its needed here.
The error you are describing shows up when a dll which is used by your xll is not found on the computer. So you have to make sure the dll is accessible to your xll.
I have a solution in VS 2008 with 2 projects in it. One is a DLL written in C++ and the other is a simple C++ console application created from a blank project. I would like know how to call the functions in the DLL from the application.
Assume I am starting with a blank C++ project and that I want to call a function called int IsolatedFunction(int someParam)
How do I call it?
There are many ways to do this but I think one of the easiest options is to link the application to the DLL at link time and then use a definition file to define the symbols to be exported from the DLL.
CAVEAT: The definition file approach works bests for undecorated symbol names. If you want to export decorated symbols then it is probably better to NOT USE the definition file approach.
Here is an simple example on how this is done.
Step 1: Define the function in the export.h file.
int WINAPI IsolatedFunction(const char *title, const char *test);
Step 2: Define the function in the export.cpp file.
#include <windows.h>
int WINAPI IsolatedFunction(const char *title, const char *test)
{
MessageBox(0, title, test, MB_OK);
return 1;
}
Step 3: Define the function as an export in the export.def defintion file.
EXPORTS IsolatedFunction #1
Step 4: Create a DLL project and add the export.cpp and export.def files to this project. Building this project will create an export.dll and an export.lib file.
The following two steps link to the DLL at link time. If you don't want to define the entry points at link time, ignore the next two steps and use the LoadLibrary and GetProcAddress to load the function entry point at runtime.
Step 5: Create a Test application project to use the dll by adding the export.lib file to the project. Copy the export.dll file to ths same location as the Test console executable.
Step 6: Call the IsolatedFunction function from within the Test application as shown below.
#include "stdafx.h"
// get the function prototype of the imported function
#include "../export/export.h"
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// call the imported function found in the dll
int result = IsolatedFunction("hello", "world");
return 0;
}
Can also export functions from dll and import from the exe, it is more tricky at first but in the end is much easier than calling LoadLibrary/GetProcAddress. See MSDN.
When creating the project with the VS wizard there's a check box in the dll that let you export functions.
Then, in the exe application you only have to #include a header from the dll with the proper definitions, and add the dll project as a dependency to the exe application.
Check this other question if you want to investigate this point further Exporting functions from a DLL with dllexport.
The following are the 5 steps required:
declare the function pointer
Load the library
Get the procedure address
assign it to function pointer
call the function using function pointer
You can find the step by step VC++ IDE screen shot at http://www.softwareandfinance.com/Visual_CPP/DLLDynamicBinding.html
Here is the code snippet:
int main()
{
/***
__declspec(dllimport) bool GetWelcomeMessage(char *buf, int len); // used for static binding
***/
typedef bool (*GW)(char *buf, int len);
HMODULE hModule = LoadLibrary(TEXT("TestServer.DLL"));
GW GetWelcomeMessage = (GW) GetProcAddress(hModule, "GetWelcomeMessage");
char buf[128];
if(GetWelcomeMessage(buf, 128) == true)
std::cout << buf;
return 0;
}
You can either go the LoadLibrary/GetProcAddress route (as Harper mentioned in his answer, here's link to the run-time dynamic linking MSDN sample again) or you can link your console application to the .lib produced from the DLL project and include the hea.h file with the declaration of your function (as described in the load-time dynamic linking MSDN sample)
In both cases, you need to make sure your DLL exports the function you want to call properly. The easiest way to do it is by using __declspec(dllexport) on the function declaration (as shown in the creating a simple dynamic-link library MSDN sample), though you can do it also through the corresponding .def file in your DLL project.
For more information on the topic of DLLs, you should browse through the MSDN About Dynamic-Link Libraries topic.
Might be useful: https://www.codeproject.com/Articles/6299/Step-by-Step-Calling-C-DLLs-from-VC-and-VB-Part-4
For the example above with "GetWelcomeMessage" you might need to specify "__stdcall" in the typedef field before the function name if getting error after calling imported function.
Presuming you're talking about dynamic runtime loading of DLLs, you're looking for LoadLibrary and GetProAddress. There's an example on MSDN.
When the DLL was created an import lib is usually automatically created and you should use that linked in to your program along with header files to call it but if not then you can manually call windows functions like LoadLibrary and GetProcAddress to get it working.
I want to make a simple, simple DLL which exports one or two functions, then try to call it from another program... Everywhere I've looked so far, is for complicated matters, different ways of linking things together, weird problems that I haven't even begun to realize exist yet... I just want to get started, by doing something like so:
Make a DLL which exports some functions, like,
int add2(int num){
return num + 2;
}
int mult(int num1, int num2){
int product;
product = num1 * num2;
return product;
}
I'm compiling with MinGW, I'd like to do this in C, but if there's any real differences doing it in C++, I'd like to know those also. I want to know how to load that DLL into another C (and C++) program, and then call those functions from it.
My goal here, after playing around with DLLs for a bit, is to make a VB front-end for C(++) code, by loading DLLs into visual basic (I have visual studio 6, I just want to make some forms and events for the objects on those forms, which call the DLL).
I need to know how to call gcc (/g++) to make it create a DLL, but also how to write (/generate) an exports file... and what I can/cannot do in a DLL (like, can I take arguments by pointer/reference from the VB front-end? Can the DLL call a theoretical function in the front-end? Or have a function take a "function pointer" (I don't even know if that's possible) from VB and call it?) I'm fairly certain I can't pass a variant to the DLL...but that's all I know really.
update again
Okay, I figured out how to compile it with gcc, to make the dll I ran
gcc -c -DBUILD_DLL dll.c
gcc -shared -o mydll.dll dll.o -Wl,--out-implib,libmessage.a
and then I had another program load it and test the functions, and it worked great,
thanks so much for the advice,
but I tried loading it with VB6, like this
Public Declare Function add2 Lib "C:\c\dll\mydll.dll" (num As Integer) As Integer
then I just called add2(text1.text) from a form, but it gave me a runtime error:
"Can't find DLL entry point add2 in C:\c\dll\mydll.dll"
this is the code I compiled for the DLL:
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
EXPORT int __stdcall add2(int num){
return num + 2;
}
EXPORT int __stdcall mul(int num1, int num2){
return num1 * num2;
}
calling it from the C program like this worked, though:
#include<stdio.h>
#include<windows.h>
int main(){
HANDLE ldll;
int (*add2)(int);
int (*mul)(int,int);
ldll = LoadLibrary("mydll.dll");
if(ldll>(void*)HINSTANCE_ERROR){
add2 = GetProcAddress(ldll, "add2");
mul = GetProcAddress(ldll, "mul");
printf("add2(3): %d\nmul(4,5): %d", add2(3), mul(4,5));
} else {
printf("ERROR.");
}
}
any ideas?
solved it
To solve the previous problem, I just had to compile it like so:
gcc -c -DBUILD_DLL dll.c
gcc -shared -o mydll.dll dll.o -Wl,--add-stdcall-alias
and use this API call in VB6
Public Declare Function add2 Lib "C:\c\dll\mydll" _
(ByVal num As Integer) As Integer
I learned not to forget to specify ByVal or ByRef explicitly--I was just getting back the address of the argument I passed, it looked like, -3048.
Regarding building a DLL using MinGW, here are some very brief instructions.
First, you need to mark your functions for export, so they can be used by callers of the DLL. To do this, modify them so they look like (for example)
__declspec( dllexport ) int add2(int num){
return num + 2;
}
then, assuming your functions are in a file called funcs.c, you can compile them:
gcc -shared -o mylib.dll funcs.c
The -shared flag tells gcc to create a DLL.
To check if the DLL has actually exported the functions, get hold of the free Dependency Walker tool and use it to examine the DLL.
For a free IDE which will automate all the flags etc. needed to build DLLs, take a look at the excellent Code::Blocks, which works very well with MinGW.
Edit: For more details on this subject, see the article Creating a MinGW DLL for Use with Visual Basic on the MinGW Wiki.
Here is how you do it:
In .h
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
extern "C" // Only if you are using C++ rather than C
{
EXPORT int __stdcall add2(int num);
EXPORT int __stdcall mult(int num1, int num2);
}
in .cpp
extern "C" // Only if you are using C++ rather than C
{
EXPORT int __stdcall add2(int num)
{
return num + 2;
}
EXPORT int __stdcall mult(int num1, int num2)
{
int product;
product = num1 * num2;
return product;
}
}
The macro tells your module (i.e your .cpp files) that they are providing the dll stuff to the outside world. People who incude your .h file want to import the same functions, so they sell EXPORT as telling the linker to import. You need to add BUILD_DLL to the project compile options, and you might want to rename it to something obviously specific to your project (in case a dll uses your dll).
You might also need to create a .def file to rename the functions and de-obfuscate the names (C/C++ mangles those names). This blog entry might be an interesting launching off point about that.
Loading your own custom dlls is just like loading system dlls. Just ensure that the DLL is on your system path. C:\windows\ or the working dir of your application are an easy place to put your dll.
There is but one difference. You have to take care or name mangling win C++. But on windows you have to take care about
1) decrating the functions to be exported from the DLL
2) write a so called .def file which lists all the exported symbols.
In Windows while compiling a DLL have have to use
__declspec(dllexport)
but while using it you have to write
__declspec(dllimport)
So the usual way of doing that is something like
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
The naming is a bit confusing, because it is often named EXPORT.. But that's what you'll find in most of the headers somwhere. So in your case you'd write (with the above #define)
int DLL_EXPORT add....
int DLL_EXPORT mult...
Remember that you have to add the Preprocessor directive BUILD_DLL during building the shared library.
Regards
Friedrich
The thing to watch out for when writing C++ dlls is name mangling. If you want interoperability between C and C++, you'd be better off by exporting non-mangled C-style functions from within the dll.
You have two options to use a dll
Either use a lib file to link the symbols -- compile time dynamic linking
Use LoadLibrary() or some suitable function to load the library, retrieve a function pointer (GetProcAddress) and call it -- runtime dynamic linking
Exporting classes will not work if you follow the second method though.
For VB6:
You need to declare your C functions as __stdcall, otherwise you get "invalid calling convention" type errors. About other your questions:
can I take arguments by pointer/reference from the VB front-end?
Yes, use ByRef/ByVal modifiers.
Can the DLL call a theoretical function in the front-end?
Yes, use AddressOf statement. You need to pass function pointer to dll before.
Or have a function take a "function pointer" (I don't even know if that's possible) from VB and call it?)
Yes, use AddressOf statement.
update (more questions appeared :)):
to load it into VB, do I just do the usual method (what I would do to load winsock.ocx or some other runtime, but find my DLL instead) or do I put an API call into a module?
You need to decaler API function in VB6 code, like next:
Private Declare Function SHGetSpecialFolderLocation Lib "shell32" _
(ByVal hwndOwner As Long, _
ByVal nFolder As Long, _
ByRef pidl As Long) As Long