implicit linking DLL question - c++

I started studying DLL's with implicit linking. I don't really fully understand how it works. Please correct me where I'm wrong.
I failed to compile the next code(3 modules):
MyLib.h
#ifdef MYLIBAPI
#else
#define MYLIBAPI extern "C" __declspec(dllimport)
#endif
MYLIBAPI int g_nResult;
MYLIBAPI int Add(int nLeft, int nRight);
As far as I understand this is the header of the DLL. #define MYLIBAPI extern "C" __declspec(dllimport) means that here we are going to declare some functions/variables that will be described in devoted .cpp file and will be contained in a DLL.
MyLibFile1.cpp
#include <windows.h>
#define MYLIBAPI extern "C" __declspec(dllexport)
#include "MyLib.h"
int g_nResult;
int Add(int nLeft, int nRight) {
g_nResult = nLeft + nRight;
return(g_nResult);
}
So, this is obviously the file where our functions are implemented. This is the part of the DLL, right?
MyExeFile1.cpp
#include <windows.h>
#include <strsafe.h>
#include <stdlib.h>
#include "MyLib.h"
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) {
int nLeft = 10, nRight = 25;
TCHAR sz[100];
StringCchPrintf(sz, _countof(sz), TEXT("%d + %d = %d"),
nLeft, nRight, Add(nLeft, nRight));
MessageBox(NULL, sz, TEXT("Calculation"), MB_OK);
StringCchPrintf(sz, _countof(sz),
TEXT("The result from the last Add is: %d"), g_nResult);
MessageBox(NULL, sz, TEXT("Last Result"), MB_OK);
return(0);
}
So, this is the executable file where we use the functions from the library.
The whole thing doesn't work. I tried to put this all into one directory and compile at once. I tried first to compile a DLL from the first two modules(successfully) and then compile the executable (changing the path to the header file). However it resulted in 2 errors both times:
error LNK2019: unresolved external symbol _WinMain#16 referenced in function ___tmainCRTStartup
\Visual Studio 2008\Projects\MyExeFile1\Debug\MyExeFile1.exe : fatal error LNK1120: 1 unresolved externals
What' s the correct way to do that - what should I change in the code and how should I compile the code (I use VS2008)?
Thanks.

#include <tchar.h> to solve the linker error.
Your header file should look like this:
#ifdef BUILDING_DLL
# define MYLIBAPI extern "C" __declspec(dllexport)
#else
# define MYLIBAPI extern "C" __declspec(dllimport)
#endif
MYLIBAPI int __stdcall Add(int nLeft, int nRight);
Right-click your DLL project in Solution Explorer, Properties, C/C++, Preprocessor, Preprocessor Definitions, add "BUILDING_DLL". Repeat for the Release configuration.
You can verify that your DLL properly exports the functions with Dumpbin.exe /exports.
The __declspec(dllimport) declarator is not strictly necessary, it does however make it more efficient. The __stdcall attribute is not necessary either, it does however make your DLL usuable from any language that supports calling DLL exports.

Change _tWinMain to WinMain in MyExeFile1.cpp. It is looking for your entry point to be named WinMain not _tWinMain and so the linker is complaining that it can't find WinMain.
There are project settings that determine what name the entry point function should be, but I'm not sure which one would require _tWinMain.
Edit
According to this posting, _tWinMain is a define that maps to WinMain if you include tchar.h.link text

Does it even compile? Shouldn't you #include <tchar.h> for all TCHAR types and definitions to work?

Related

Exporting extern variables from dll visual C++

Basically I have a dll project in visual studio. I'm linking this dll project to a second project successfully but as soon as I try to use extern variables things go wrong. I've seperated my extern variables into a single header and source file from everything else so I can isolate the problem and potential solutions. I've scowered the internet for hours now and I feel like I've tried everything. I am beginning to think it might be a compile flag? Anyway, heres my code.
macros.h
#pragma once
// dll management
#ifdef TOAST_EXPORT
#ifdef _MSC_VER
#define TAPI __declspec(dllexport)
#else
#define TAPI __attribute__((visibility("default")))
#endif
#else
#ifdef _MSC_VER
#define TAPI __declspec(dllimport)
#else
#define TAPI
#endif
#endif
globals.h
#pragma once
#define TOAST_EXPORT
#include "macros.h"
namespace toast
{
TAPI extern const char c;
}
globals.c
Note that I tried this without const and made no assignment here
#pragma once
#include "globals.h"
namespace toast
{
const char c = 'a';
}
main.c (from the project that compiles to an exe)
#include <globals.h>
int main()
{
char c = toast::c;
return 0;
}
So far I've tried making a lot of subtle changes like reordering extern and const and such. I've also done it both with just extern and just const. Still produces the same unresolved external symbol "char const toast::c" error. Keep in mind that I can create instances of classes and call their methods from the dll successfully and thats with things like class TAPI logger... and such.

complie dll but appear error LNK2019

I implement a C++ function as DLL with vs2013. But I have linker error (error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup) building to the dll. I have proper setup and not sure what is wrong. The code is very simple, but I don't know why it can't be built successfully.
Demoone.h
#ifndef _Demo_H_
#define _Demo_H_
#ifdef LIBDLL
#define LIBDLL extern "C" _declspec(dllimport)
#else
#define LIBDLL extern "C" _declspec(dllexport)
#endif
LIBDLL int Add(int plus1, int plus2);
#endif
Demoone.cpp
#include "Demoone.h"
int Add(int a, int b)
{
return (a + b);
}
update:
I modified the header file as bellow
#ifndef _Demo_H_
#define _Demo_H_
extern "C" int Add (int a , int b);
#endif
and add an def file
LIBRARY "Dllmaketwo"
EXPORTS
Add # 1
The same linker error (error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup) also appeared.
If you want to use load-time linking in the project that uses the DLL you need to link against the .lib produced by the DLL project build.
You can do that with:
#pragma comment(lib, "dllproject.lib")
Or by adding the .lib to the additional dependencies line in the project settings under Linker->Input. You may also need to mess with the library search path, either in the VC++ Directories page or in the Linker->General page.
#ifndef _Demo_H_
#define _Demo_H_
#ifdef LIBDLLIMPORT //Changed here
#define LIBDLL extern "C" _declspec(dllimport)
#else
#define LIBDLL extern "C" _declspec(dllexport)
#endif
LIBDLL int Add(int plus1, int plus2);
#endif
You should not use a same name in #ifdef and #define,
Did you setup you project correctly? And you should not write a `main()' function in it.

Using a C/C++ DLL with FreePascal

First of all I am using Mingw 4.8 as the compiler of the C++ DLL in Code:blocks 13.12 and Lazarus 1.4.2 for working with the pascal code.(windows 7)
I need to generete a dll in c++ or c that can be called from a pascal program.
The problem is that my knowlegde about pascal is null, It dosn't look really complicate to make a simple program but I can't find good information about how to import and use a C/C++ DLL.
The only thing that moreless worked was this: http://www.drbob42.com/delphi/headconv.htm
My real code:
Pascal:
funtion hello():Integer; external 'function' index 1;
...
Label1.Caption:=IntToStr(hello());
C++ DLL header:
#ifndef function_H
#define function_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILDING_DLL
#define FUNCTION_DLL __declspec(dllexport)
#else
#define FUNCTION_DLL __declspec(dllimport)
#endif
int __stdcall FUNCTION_DLL hello( );
#ifdef __cplusplus
}
#endif
#endif
C++ file:
#include <stdio.h>
#include "function.h"
__stdcall int hello( )
{
return 8;
}
But when try to pass any argument or do something complicated with the function,starts to give randoms numbers.
This is the new code:
Pascal:
function function1(t1:Integer):Integer; external 'function' index 1;
...
entero:=8;
Label1.Caption:=IntToStr(function1(entero2));
Also I update the c++ code to this:
C++:
#include <stdio.h>
#include "function.h"
__stdcall int function1(int t1)
{
return t1*2;
}
Header:
#ifndef funtion_H
#define funtion_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILDING_DLL
#define FUNCTION_DLL __declspec(dllexport)
#else
#define FUNCTION_DLL __declspec(dllimport)
#endif
int __stdcall FUNCTION_DLL function1(int t1);
#ifdef __cplusplus
}
#endif
#endif
I aslo read this other info:http://www.jrsoftware.org/ishelp/index.php?topic=scriptdll. And tried to implement the dll call like this:
Pascal:
function function1(t1: Integer): Integer; external 'function1#files:function.dll';
But I receive an error saying that:
The procedure entry point function1 could not be located in the
dynamic link library function.dll
I'm looking for an example that works or a online tutorial or something to continue working because I am very stuck with this.
Thank you in advance.
You need to make the calling conventions match. Your C++ code uses __stdcall. The Pascal code does not specify a calling convention and so defaults to register.
Declare the Pascal import like this:
function function1(t1:Integer):Integer; stdcall; external 'function' index 1;
Are you quite sure that you need to use an index when importing? It is much more common to import by name than by ordinal. I'd expect to see the import looking like this:
function function1(t1:Integer):Integer; stdcall; external 'function';
The reason why the function with no parameters succeeds is that for a parameterless function, the differences between calling convention do not matter. Once you start passing an argument, stdcall means that the argument is passed via the stack, and register means it is passed in a register. This mismatch explains the behaviour you observe.

Having trouble importing function from C++ dll error LNK 2019

I am trying to write and test a dll file in C++ that I can call whenever I want filesystem level access to things. I am currently having a huge headache when trying to access the methods in this dll in C++. Strangely enough, I was able to call the code in a separate C# program with little trouble, but I want to get an understanding of how dll interaction works in C++.
And this is the .cpp for my dummy executable that should only call my "newMain" test method.
// dummy.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
//#pragma comment(lib,"visa32.lib")
#pragma message("automatic link to adsInterface.dll")
#pragma message(lib, "adsInterface.lib"
extern "C" int __stdcall newMain();
int _tmain(int argc, _TCHAR* argv[])
{
newMain();
std::string i;
std::cin >> i
return 0;
}
The problem is, when I run it I get this error:
error LNK2019: unresolved external symbol _newMain#0 referenced in function _wmain
error LNK1120: 1 unresolved externals
Here is the .h for adsInterface:
// adsInterface.h
#ifndef ADSINTERFACE_H
#define ADSINTERFACE_H
/* //save this for later i have no clue how this really works.
#ifdef ADSAPI_EXPORTS
#define ADSAPI __declspec(dllexport)
#else
#define ADSAPI __declspec(dllexport)
#endif
*/
namespace ADSInterface
{
//test method. should print to console.
__declspec(dllexport) int __stdcall newMain();
void hello();
}
#endif
and here is my .cpp for adsInterface:
// adsInterface.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "adsInterface.h"
#include <iostream>
namespace ADSInterface
{
/* this is where the actual internal class and other methods will go */
void hello()
{
std::cout << "hello from the DLL!" << std::endl;
}
__declspec(dllexport) int __stdcall newMain()
{
hello();
return 0;
}
}
I'll also include the .def file i used when compiling the dll:
; adsInterface.def - defines exports for adsInterface.dll
LIBRARY ADSINTERFACE
;DESCRIPTION 'A C++ dll that allows viewing/editing of alternate data streams'
EXPORTS
newMain #1
Strangely enough, I was able to import the method in C# with this line (I did not have to include a .lib file either):
[DllImport("./adsInterface.dll")] private static extern void newMain();
And it ran when I called it normally:
newMain();
I've been reading many different guides on how to import dll functions, and I've reached the point where I think I'm just mangling together different ways of importation between the languages and just making a mess of things. If anyone is able to provide some insight on how I should be importing dll methods in C++ that would be much appreciated.
delete this declaration:
extern "C" int __stdcall newMain();
and call ADSInterface::newMain() from _tmain.
In the posted code you did not define anything matching that declaration, did you?
Alternatively make the implementation calling the other one, or drag the one from namespace to global.

basic_string<TCHAR> doesn't allow definition outside the place it's declared

okay, i'm a bit befuddled with this error. What i'm trying to do here is make a basic_string that will be either char or wchar_t when UNICODE and _UNICODE are defined (this is in WINAPI). This does work, but for some reason, i'm unable to define a function that receives a std::basic_string outside the class where it's declared. Here's an example:
test.h
#ifndef TEST_H
#define TEST_H
#include <Windows.h>
#include <string>
class Test
{
public:
void func(std::basic_string<TCHAR> stringInput);
};
#endif
test.cpp
#include "test.h"
void Test::func(std::basic_string<TCHAR> stringInput)
{
MessageBox(NULL, stringInput.c_str(), TEXT("It works!"), MB_OK);
}
This yields a link error, claiming the test::func was never defined. However, if i just define inside the class like this:
test.h
#ifndef TEST_H
#define TEST_H
#include <Windows.h>
#include <string>
class Test
{
public:
void func(std::basic_string<TCHAR> stringInput)
{
MessageBox(NULL, stringInput.c_str(), TEXT("It works!"), MB_OK);
}
}
#endif
it works fine. However, i really like to keep my declarations and definitions in separate files to avoid redefinition errors and for organization. Here's the kicker though. when i have func defined in test.cpp like before and don't define UNICODE and _UNICODE in my main.cpp, i don't get the link errors. So really, the only time i get a link error is when TCHAR becomes a wchar_t. So here's my main and the error real quick...
main.cpp
#define UNICODE // this won't compile when these are defined
#define _UNICODE
#include <Windows.h>
#include <string>
#include "test.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
Test test;
test.func(TEXT("wakka wakka"));
return 0;
}
error:
error LNK2019: unresolved external symbol "public: void __thiscall Test::func(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >)" (?func#Test##QAEXV?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###Z) referenced in function _WinMain#16
Anyone have a clue what's going on and how i might go about fixing this?
I think because you are putting #define UNICODE in main.cpp, the other part doesn't know about this. When test.cpp is compiled, UNICODE is not defined. You can try putting the UNICODE definition as project processor macro. Or in test.h, write #define UNICODE and #define _UNICODE before including Windows.h .
On another note, because you've included Windows.h in Test.h, you should not include it again in main.cpp .
Consider create a default project in visual studio, and use Precompiled Headers. This way, put such include in stdafx.h will address all your problems:
#define UNICODE
#include <windows.h>
#include <string>