I use eclipse and mingw compilier (c++).
I would like to create a dll file which contains a lot of strings.
After that I would like to call with LoadString() to read the string (http://msdn.microsoft.com/en-us/library/windows/desktop/ms647486(v=vs.85).aspx)
my dll file:
#define WIN32_LEAN_AND_MEAN
#define DLL_FUNC extern "C" __declspec(dllexport)
DLL_FUNC int __stdcall Hello() {
return 0;
}
my cpp file:
#include <windows.h>
#include <stdio.h>
int main () {
typedef int (__stdcall *HelloProc)();
HMODULE hdll = LoadLibrary("HelloWorld.dll");
if( hdll == NULL){
MessageBox(HWND_DESKTOP, "Wrong dll path", "Message", MB_OK);
}
else {
typedef int (__stdcall *HelloProc)();
HelloProc Hello = (HelloProc)GetProcAddress(hdll, "Hello#0");
if(Hello == NULL){
//LoadString();
MessageBox(HWND_DESKTOP, "Hello is NULL", "Message", MB_OK);
}
else{
Hello();
}
}
return 0;
}
How do I create the strings? And how to call with LoadString()?
I think you want to read about resources so that you can build a resource-only DLL containing a string table. Try searching the MSDN site you referenced for things like resource compiler and maybe how to build a resource only DLL and how to use string tables. I'm sure you will find documentation and examples at Microsoft and, if not, with Google.
Oh, your DLL is not required to be resource only, I got that from your comment "I would like to create a dll file which contains a lot of strings." It is actually even easier (maybe more straightforward) to do if your DLL will also contain code. Then you'd want to search for adding resources to a DLL and things like that.
Related
I am trying to export a function pointer for a function to be called. What I am after is when a function in a dll/exe needs to call a function exported by another library it gets the function pointer and calls that. The reason for this is I want to provide a hooking mechanism and I figured function pointers would be the quickest and easiest way because I can change what they point to easily are runtime.
So I found this Exporting a function pointer from dll and I cant get it to work. Whenever I call it to get the function pointer I get an error that it cant find the entry point. So the error isnt that the function pointer is working but the function to get the function pointer isnt working. I believe it is a function signature issue. Here is an example:
Colors.h
#ifndef __COLORS
#define __COLORS
#ifdef MYDLL_EXPORTS
/*Enabled as "export" while compiling the dll project*/
#define DLLEXPORT __declspec(dllexport)
#else
/*Enabled as "import" in the Client side for using already created dll file*/
#define DLLEXPORT __declspec(dllimport)
#endif
#include <string>
#include <vector>
class Colors
{
private:
std::string myColor;
static DLLEXPORT std::vector<std::string> allColors;
public:
Colors(){};
Colors(std::string MyColor);
virtual DLLEXPORT std::string getMyColor();
virtual DLLEXPORT void addToColors(std::string color);
std::vector<std::string> getAllColors();
};
typedef Colors* (*create)(std::string);
DLLEXPORT create createColors();
Colors* createColors2(std::string color);
#endif
colors.cpp
#define MYDLL_EXPORTS
#include "Color.h"
std::vector<std::string> Colors::allColors;
Colors::Colors(std::string MyColor)
{
this->myColor = MyColor;
this->allColors.push_back(this->myColor);
}
std::vector<std::string> Colors::getAllColors()
{
return this->allColors;
}
std::string Colors::getMyColor()
{
return this->myColor;
}
Colors* createColors2(std::string color)
{
return new Colors(color);
}
DLLEXPORT void Colors::addToColors(std::string color)
{
this->allColors.push_back(color);
}
DLLEXPORT create createColors()
{
return &createColors2;
}
main.cpp
#define MYDLL_EXPORTS
#include <iostream>
#include <Windows.h>
#include "Color.h"
int main()
{
Colors red("red");
Colors blue("blue");
Colors* dlltest;
//Define the function prototype
typedef Colors* (*createNewColor)();
BOOL freeResult, runTimeLinkSuccess = FALSE;
HINSTANCE dllHandle = NULL;
createNewColor dllCreateNewColor = NULL;
//Load the dll and keep the handle to it
dllHandle = LoadLibrary(L"libs/testerdll.dll");
// If the handle is valid, try to get the function address.
if (NULL != dllHandle)
{
//Get pointer to our function using GetProcAddress:
dllCreateNewColor = (createNewColor)GetProcAddress(dllHandle,"createNewColor");
// If the function address is valid, call the function.
if (runTimeLinkSuccess = (NULL != dllCreateNewColor))
{
dlltest = dllCreateNewColor();
std::cout << "Color of dll class: " << dlltest->getMyColor() << std::endl;
}
else
{
std::cout << "Failed to locate function" << std::endl;
}
//Free the library:
//freeResult = FreeLibrary(dllHandle);
}
else
{
std::cout << "Failed to load library" << std::endl;
}
std::vector<std::string> colorslist = red.getAllColors();
for (std::string color : colorslist)
{
std::cout << color << std::endl;
}
return 0;
}
Dll project
dllmain.cpp
// testerdll.cpp : Defines the exported functions for the DLL application.
#include "stdafx.h"
#include "Color.h"
__declspec(dllexport) Colors* createNewColor()
{
create temp1 = createColors(); //seems to fail here
return nullptr;
}
Yes I know I have memory leaks etc. this was just a quick example code to replicate the problem.
To return the function, you need to get it's address, and return that
e.g.
__declspec(dllexport) create createNewColor()
{
create temp1 = createColors;
return temp1;
}
However, this system (using std::string as a return type, requires that both the .exe and the .dll use the same DLL based runtime library.
stackoverflow : passing reference to STL over function boundary
C++ does not define a calling convention between files. This means that different compilers may set up C++ objects slightly differently. Microsoft limited that with the definition of COM, but that still is a possibility.
Also for visual studio, there are separate heaps (new / delete) between runtime instances. When you link against the dynamic library, all dlls and exes in the process share this DLL. But then they all need to be updated together.
So this process can work, but be wary about :-
Sharing C++ types between binaries (DLL/EXE) - no ABI
Using new in DLL, and delete in EXE. (different heaps).
STL objects are also problematic, as they are a mixture of header implementation (compiled into the binary), and DLL implementation (compiled into C++ runtime).
Okay so I'm coming dangerously close to a repost here but my situation is a little bit different than the numerous other posters about this function. I am interfacing with a DLL that was written way back in the day and all I have is the file. I don't have a .lib file so I'm using the LoadLibrary and GetProcessAddress functions. I followed the tutorial on the MSDN website to get the basic structure. the DLL is located in the project folder. it compiles. at run time, I am getting a numerical value for "hinstLib" so I'm assuming the DLL was found. I am getting a null value for "ProcAdd" variable. Other posters had there issues resolved by putting extern C in the DLL functions but I don't really have that option. not to mention, to my knowledge this DLL was written in plain C. I do have an interface document and am quite sure I have the function name correct (replaced with a generic example for these purposes). I honestly didn't run anything past the ProcAdd assignment because it came out NULL. Any thoughts as to why this is giving me a 0 value for the function assignment would be great appreciated. Note: unfortunately due to various reasons I can't upload the DLL.
#include <iostream>
#include "stdafx.h"
#include "Windows.h"
#include <stdio.h>
typedef int(__cdecl *MYPROC)(LPWSTR);
using namespace std;
int main()
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
hinstLib = LoadLibrary(TEXT("dllName.dll"));
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "funcName");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
//(ProcAdd) (L"Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
return 0;
}
Compilers usually mangle function names, then a function named funcName may appear inside the DLL with a name funcName#16 , for example... It depends on calling convention and are important for a function to be called properly. For __cdecl calling convention you probably need _funcName :-) .
I have created an *.exe and *.dll for my project.
I have provided all the correct path and data.
Myexe.cpp:
#include "stdafx.h"
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hInstLibrary = LoadLibrary(L("..\\Debug\\LoadDLL\\LoadDLL.dll"));// I have checked with complete path as well.
if(hInstLibrary)
{
printf("Hello World");
}
return 0;
}
MyDLL.cpp:
#include "MyDLL.h"
#include <stdio.h>
MyDLL::MyDLL(void)
{
}
MyDLL::~MyDLL(void)
{
}
extern "C" __declspec(dllexport) void HelloWorld()
{
printf("Hello DLL");
}
MyDLL.h:
#pragma once
class __declspec(dllexport) MyDLL
{
public:
MyDLL(void);
~MyDLL(void);
};
extern "C" __declspec(dllexport) void HelloWorld();
I have tried providing the complete path also. But it is still failing. The hInstLibrary is setting to 0x00000. I tried in Release mode too but the problem still lies there.
But when I have tried with:
HMODULE hInstLibrary = LoadLibrary(_T("C:\\Windows\\System32\\aeinv.dll"));
it does load the DLL. So, please help me where is it going wrong. The DLL gets build properly, there is absolutely no error in building DLL. Then why am I facing this problem??
Is there any setting need to be done for Debug.
You need to call GetLastError to find out what went wrong.
Edit:
You got 0x7e, which means:
ERROR_MOD_NOT_FOUND
126 (0x7E)
The specified module could not be found.
Your path is wrong. You need to fix that.
Inspect your executable with DependencyWalker and the profile it from there. You'll get a better picture as to why your dll fails to load and how the dependency tree looks like.
When you start profiling (F7) make sure that 'Log LoadLibrary function calls' is checked.
You can also check Dynamic-Link Library Search Order to see if anything is applicable to your specific case.
What's L in L("..\\Debug\\LoadDLL\\LoadDLL.dll")? You probably meant L"..\\Debug\\LoadDLL\\LoadDLL.dll" without the parentheses for a wide-char string. I'm not sure how that compiles unless you created an L macro? The _T(x) macro expands to L ## x (in wide-char builds), by the way...
I created a DLL file (helloWorld.dll):
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define DLL_FUNC extern "C" __declspec(dllexport)
DLL_FUNC int __stdcall Hello() {
MessageBox(HWND_DESKTOP, "Hello, world", "MEssage", MB_OK);
return 0;
}
After that I created a cpp where I would like to call (useDLL.cpp)
#include <windows.h>
#include <stdio.h>
int main () {
typedef void (*pfunc)();
HINSTANCE hdll = LoadLibrary("HelloWorld.dll");
pfunc Hello;
Hello = (pfunc)GetProcAddress(hdll, "hello");
Hello();
return 0;
}
How can I call the Hello() function?
The code in the question contains a number of errors:
LoadLibrary returns HMODULE and not HINSTANCE
The function pointer has the wrong return value and an incorrect calling convention.
Function names are case sensitive and you must account for name decoration.
You did no error checking at all. Your code probably fails on the call to GetProcAddress, returns NULL and then bombs when you try to call the function at NULL.
So you need something like this:
typedef int (__stdcall *HelloProc)();
....
HMODULE hdll = LoadLibrary("HelloWorld.dll");
if (hdll == NULL)
// handle error
HelloProc Hello = (HelloProc)GetProcAddress(hdll, "_Hello#0");
if (Hello == NULL)
// handle error
int retval = Hello();
The function name is decorated because you used __stdcall. If you had used __cdecl, or a .def file, then there would have been no decoration. I'm assuming MSVC decoration. It seems that decoration differs with your compiler, mingw, and the function is named "Hello#0".
Frankly it's much easier to do it with a .lib file instead of calling LoadLibrary and GetProcAddress. If you can, I'd switch to that way now.
You need to specifically search and find specific functions you are lookins for, check out this link:
Calling functions in a DLL from C++
I am trying to import a dll to a C# console application just to see if I can get a dll to work as a want, when trying this and exporting functions with C-code everything works fine and the functions can be imported in my C# application.
The problem starts when I try to add some kind of linkage to some QT methods in my unmanaged dll. I'm using DllImport to import the functions from the dll.
[DllImport("cDLL.dll", EntryPoint = "_Add#16")]
static extern double Add(double a, double b);
1 - This is how the unmanaged dll (don't look at the functionality of the code, this is just for testing purposes) looks like when it works fine.
main.cpp working
#include <stdexcept>
#include "Windows.h"
using namespace std;
extern "C" __declspec(dllexport) double __stdcall Add(double a, double b)
{
return a + b;
}
extern "C" __declspec(dllexport) const char* getText()
{
return "hello world";//returnBufferString.c_str();
}
BOOL __stdcall DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) {
return TRUE;
}
2 - When I try to add a help function with some QT code, just an ordinary QString the DllImport starts throwing dllNotFoundException.dumpbin.exe shows all the exported functions as well after including the qt code...
main.cpp dllNotFoundException
#include <QString>
using namespace std;
class testa
{
public:
static char* test()
{
QString a = "hejsan";
return qString2Char(a);
}
static char* qString2Char(QString a)
{
return a.toUtf8().data();
}
};
This is called from the getText() function like this:
string returnBufferString;
extern "C" __declspec(dllexport) const char* getText()
{
returnBufferString = testa::test();
return returnBufferString.c_str();
}
When I try to access the dll from DllImport I get dllNotFoundException in the 2:nd part. How do I solve this? have I missed any dependencies or anything. My dll is build using msvc2010 compiler and the .pro file looks like this:
cDLL.pro
TEMPLATE = lib
CONFIG += dll
QT += core
# Input
SOURCES += main.cpp
I'm stuck...
It doesn't tell you exactly what DLL it cannot find. Which is almost surely not your DLL, it is one of the DLLs that QT requires. You'd have to copy them to the EXE folder as well. If you have no idea and can't find it in the Nokia documentation then you can find out with SysInternals' ProcMon utility.
However, in this scenario you surely want to link QT into your DLL since the odds that those DLLs can be shared are small. Use this SO question for guidance in setting up your QT project.
You need to put the DLL in the same folder as your executable.
See http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx