How to reference a dll to Visual Studio without lib file - c++

I needed to add a third party library to my project, and they only supply a .dll file (no .lib)
I have added the dll to the project by going to the project Property Page under Common Properties -> References -> Add New Reference
I can see the dll under the External Dependencies folder in the Solution Explorer, so I guess it was included correctly.
But how do I reference the dll?
When I try to add an instance variable (For example, MCC::iPort::ASCII iPort) to access the dll class, I get Error: name followed by '::' must be a class or namespace name, but I know thats the class name I can see it in the dll info under External Dependencies.

The only way to access a bare DLL without a .lib file is to load the DLL explicitly with LoadLibrary(), get pointers to the exported functions you want to access with GetProcAddress(), and then cast those pointers to the proper function signature. If the library exports C++ functions, the names you have to pass to GetProcAddress() will be mangled. You can list the exported names with dumpbin /exports your.dll.
extern "C" {
typedef int (*the_func_ptr)( int param1, float param2 );
}
int main()
{
auto hdl = LoadLibraryA( "SomeLibrary.dll" );
if (hdl)
{
auto the_func = reinterpret_cast< the_func_ptr >( GetProcAddress( hdl, "the_func" ) );
if (the_func)
printf( "%d\n", the_func( 17, 43.7f ) );
else
printf( "no function\n" );
FreeLibrary( hdl );
}
else
printf( "no library\n" );
return 0;
}
As has been noted by others, a LIB file can be created. Get the list of exported functions from dumpbin /exports your.dll:
ordinal hint RVA name
1 0 00001000 adler32
2 1 00001350 adler32_combine
3 2 00001510 compress
(etc.)
Put the names into a DEF file:
EXPORTS
adler32
adler32_combine
compress
(etc.)
Now make the LIB file:
lib /def:your.def /OUT:your.lib
For cases where the name has been decorated, either by C++ name mangling or 32-bit stdcall calling convention, simply copy and paste whatever names dumpbin reported, mangling and all.

If you don't have a .lib file you can create one from the .dll:
https://web.archive.org/web/20160228170508/https://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/

Related

Exporting function names from C++ Dll to Delphi

I have a working DLL written in C++ with Visual Studio 2015. It contains many functions of the form:
BECALIBRARY_API int Functions::GetVersion(char* ptrVersionString)
{
char * Version;
Version = "Test 123456";
strcpy_s(ptrVersionString, strlen(Version) + 1, Version);
return strlen(Version);
}
The Delphi function to retrieve this is:
unit uBecaLibrary;
interface
function getVersion(Str1: pAnsichar): integer; stdCall;
implementation
function getVersion; external 'BecaLibrary.dll' index 1;
//function getVersion; external 'BecaLibrary.dll' name 'getVersion';
end.
This works fine except that I have to maintain the Delphi code using the index numbers of the DLL.
What do I need to do to both the C++ side and the Delphi Seattle Windows 10 side to use function names rather than indexes.
You can use dumpbin utility to view exported names as
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\dumpbin.exe" /EXPORTS BecaLibrary.dll
Names will probably be mangled but it should not be a problem.
If you can change DLL, you can add following inside function body to export unmangled name
#pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)
You can just use the function name on the last like this
var
function getVersion(Str1: pAnsichar): integer; stdCall; external 'BecaLibrary.dll' name 'GetVersion';
implementation
For the DLL
To export an undecorated name, you can link by using a Module Definition (.def) file that defines the undecorated name in an EXPORTS section. For more information, see EXPORTS. Another way to export an undecorated name is to use a #pragma comment(linker, "/export:alias=decorated_name") directive in the source code.
When you declare dllexport or dllimport, you must use extended attribute syntax and the __declspec keyword.
Source: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx

Windows CE .EXE symbol access from DLL

I have some code which is working on Unix (Linux and Solaris) and Windows (7 to be exact) but doesn't work on Windows CE. This code implements a plug-in framework and requires exporting symbols from the executable into the loaded plug-ins. I am unable to get the loaded plug-ins (DLLs) to resolve symbols from the main executable.
I have reduced the interface to a single function in the main executable which is defined as such:
extern "C" __declspec( dllexport )
const char * translate_name( const char *key ) {
...
}
If I run Dumpbin /EXPORTS on the executable I see this as one of the exported symbols:
81 50 00001474 translate_name = #ILT+1135(_translate_name)
The plug-ins are required to export two functions xxxLoadPlugin and xxxUnloadPlugin which the main executable will call after loading to allow them to interconnect. The xxx is replaced with an agreed upon name prefix (usually the dll or .so name). I have a test project which creates:
extern "C" __declspec( dllexport ) int testRegisterLibrary( ) {
return 0;
}
extern "C" __declspec( dllexport ) int testUnregisterLibrary( ) {
return 0;
}
If I compile and run this module everything will work as expected. I can load the dll, and walk through the functions in my debugger.
If I add code which references translate_name, such as:
extern "C" __declspec( dllimport ) const char * translate_name( const char *key );
extern "C" __declspec( dllexport ) int testRegisterLibrary( ) {
translate_name("test");
return 0;
}
extern "C" __declspec( dllexport ) int testUnregisterLibrary( ) {
return 0;
}
the DLL will now fail to load. Checking the created DLL with dumpbin /IMPORTS I see:
50 translate_name
translate_name is the only symbol imported from my main executable. If I try using GetProcAddress instead of relying on the linker, like this:
extern "C" __declspec( dllexport ) int testRegisterLibrary( ) {
HMODULE mainModule = GetModuleHandle(NULL); //handle for main executable
void *ptr = (void *)GetProcAddress(L"translate_name");
return 0;
}
extern "C" __declspec( dllexport ) int testUnregisterLibrary( ) {
return 0;
}
The DLL loads, but the value of 'ptr' is NULL (checked inside a debugger). I've also tried GetProcAddressA("translate_name"), and using "_translate_name" with the same results.
Given this it seems that the symbols that were exported by the executable are not retained after the initial loader pass in windows CE. Again, this works in any normal windows environment. Is there some setting I'm missing for windows CE? Why can GetProcAddress not find a symbol in the executable which dumpbin says is exported? Are the symbols being hidden or dropped by the windows CE loader?
Just to confirm your findings, this doesn't work. It is difficult to find hard evidence in the MSDN docs that this is not supported, other than that GetProcAddress() is adamant that the symbol must be exported by a DLL. You can't get the DLL loaded, it will fail with ERROR_BAD_EXE_FORMAT when it contains the import from the EXE. GetProcAddress() will always fail with ERROR_INVALID_HANDLE, even if you force the module handle to the EXE load address.
There's no strong evidence that the loader intentionally strips the export table of the EXE, it is resident in memory when you look with the debugger. It just categorically refuses to look at it.
You'll need to punt this problem and tackle this a different way. Beyond spinning off the helper functions in a separate DLL, an obvious workaround is that you provide the xxxLoadPlugin() entrypoint with an argument, a pointer to table of function pointers to the helper functions. The common IServiceProvider interface used in COM is a good approach.

making an VC++ .exe to DLL .is it possible?

I have an VC++ win 32 application which compiles into an EXE. But now I want to convert it into dll so that I can load that in another application.I tried changing in Visual Studio properties from .EXE to .DLL which successfully converted it but whn i use GetProcAddress it always returns NULL . I am not sure what I am doing is right or wrong .
Basically this what I want to achieve :
I want to link project 1 and project2
Project 2 should be able to invoke the functions of project1(which is an exe currenlty)
EDIT
Hi guys thanks for your input .I told what you guys said . even then my GetProcAddress returns zero . Am i am doing anything wrong .Shown my dll loading code below .
HINSTANCE LoadMe = LoadLibrary( _T("D:\\VC++Project\\CVAList\\CVAList\\ExportTest.dll"));
if (LoadMe != 0)
printf("LoadMe library loaded!\n");
else
printf("LoadMe library failed to load!\n");
EntryPointfuncPtr LibMainEntryPoint;
LibMainEntryPoint = (EntryPointfuncPtr)GetProcAddress(LoadMe,"PrintFloatsVal");
LibMainEntryPoint (a1 ,a,b,c,d ); // 4 double
EDIT DLL Export Code
#define DllExport __declspec( dllexport )
DllExport void PrintFloatsVal ( int amount, double &d1 ,double &d2 , double &d3 ,double &d4)
{
....
..
}
You need to export the functions you wish to access using the __declspec dllexport keyword.
So if you add the manifest constant 'BUILDING_MY_DLL' to the project, the header file that declares the functions you care about can be used in both the DLL project and any code that uses the DLL:
#ifdef BUILDING_MY_DLL
#define MY_DLL_EXPORT __declspec dllexport
#else
#define MY_DLL_EXPORT __declspec dllimport
#endif
And decorate the functions you wish to export:
MY_DLL_EXPORT BOOL Func1(int a);
If the function you wish to access is implemented in C++ it will be decorated, for the purposes of function overloading and other purposes, and it best accessed directly like any other function. If you wish to use GetProcAddress() however you are better off giving it C-linkage by surrounding the function with extern "C" { ... }. This will make the exported name the same the name used within the code.
Reference: http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx

Calling functions in a DLL from C++

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.

Compile a DLL in C/C++, then call it from another program

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