VS2013 C++ Compiler Mangling name defined with extern "C" - c++

I'm trying to build a WIN32 console app that uses the current 2.12.28 ftd2xx.lib static library from FTDI. I'm using VS2013 and native unmanaged C++. My call looks like this.
#include "../ftd2xx.h"
. . .
DWORD port_count = 0;
FT_STATUS status = FT_OK;
status = FT_CreateDeviceInfoList(&port_count);
When I compile I get a link error
GetTopazVCP.obj : error LNK2019: unresolved external symbol __imp__FT_CreateDeviceInfoList#4 referenced in function "unsigned long __cdecl Get1stVirtualComPort(unsigned long *)" (?Get1stVirtualComPort##YAKPAK#Z)
The unresolved symbol __imp__FT_CreateDeviceInfoList#4 appears to be a mangled name version of the FT_CreateDeviceInfoList function. So it's not being resolved in the ftd2xx.lib which uses C naming. What I don't understand is why the compiler mangled the name when the ftd2xx.h file has a conditional extern "C"
#ifdef __cplusplus
extern "C" {
#endif
. . .
FTD2XX_API
FT_STATUS WINAPI FT_CreateDeviceInfoList(
LPDWORD lpdwNumDevs
);
...
#ifdef __cplusplus
}
#endif
wrapping all the FT_??? declarations. I have confirmed that __cplusplus is defined during the compile. Any ideas what is causing the unexpected name mangling?

As ChronoKitsune pointed out in his comment there is no name mangling here. The problem was I was linking the static version of the FTDI library but the default for the ftd2xx.h header file is to declare the FT_??? functions as calls to the DLL version. When I replaced the ftd2xx.lib static version with the ftd2xx.lib DLL version it built successfully. FTDI only supplies one version of the ftd2xx.h header and looking closely inside it I discovered that if you want to use the static ftd2xx.lib you need to #define FTD2XX_STATIC before including ftd2xx.h
#define FTD2XX_STATIC
#include "ftd2xx.h"

Related

Standard method for creating dll in c++ and calling in delphi

I am looking for the correct method to create a DLL in C++ and call it in Delphi. I use CodeBlocks for the DLL and Delphi RAD Studio 10.2.
My C++ header and source code for building the DLL as described in How to create dll in C++ for using in C# is as follows:
Main.h:
#ifndef MATH_HPP
#define MATH_HPP
extern "C"
{
__declspec(dllexport) int __stdcall math_add(int a, int b);
}
#endif
Main.Cpp :
#include "main.h"
int __declspec(dllexport) __stdcall math_add(int a, int b)
{
return a + b;
}
This code in CodeBlocks builds math_dll.dll without any error.
Calling the DLL in Delphi:
function math_add(X, Y: Integer): Integer; stdcall; external 'math_dll.dll' name 'math_add';
But when I run Delphi and call this function, I have the following error:
"the procedure entry point math_add could not be located in the dynamic link library math_dll.dll"
Which part of my code is wrong?
The default name mangling for the __stdcall calling convention is _<name>#<bytes_in_arguments>. So your DLL function is most likely being exported as '_math_add#8' instead of as 'math_add' like you are expecting. Use a tool like PEDUMP to verify that.
You can use a .DEF file when compiling the DLL to change the exported name, or you can update your Delphi function declaration to use the correct exported name for the name attribute.

c++ dll function export naming conventions (mangling)

I am totally new in C++ and starting with creating a simple dll and console app that tests the dll. The dll plugin afterwards should work on x86 machines (diag tools, ECU or PLC). The samples given to me that I fallow the same structure exports dll function as __sdcall. so my helloWorld project looks like:
plugin.dll
-----------
plugin.h
#pragma once
#include "types.h"
#define EXPORT extern "C" __declspec (dllexport)
EXPORT S32 WINAPI Greetings(string *str);
plugin.cpp
#include "plugin.h"
#include "types.h"
S32 __stdcall Greetings(string *str){*str = "Hello From Plugin!"; return -1;}
and the console app looks like: (both are in same solution, project/properties/cc++/adnvances/callingConvention = __cdecl (/Gd))
VS settings - Solution configuration=debug, Solution Platforms=x86
main.cpp
HMODULE DllHandler = ::LoadLibrary(L"plugin.dll");
string greetingText;
typedef U32(*Type)(string*);
Type greetings = reinterpret_cast<Type>(GetProcAddress(DllHandler, "Greetings"));
greetings(&greetingText);
cout << greetingText << endl;
Now, without plugin.def the GetProcAddress(DllHandler, "Greetings") returns null (0x000000) with the plugin.def (alongside with EXPORT) I get the Greetings with decoration plugin.dll!Greetings#4 the call will succeed but get
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
also no casting with naming convention is allowed.
I red many posts about __cdecl __stdcall but mostly explaining the assembly level that who cleans the stack, or using either .def or extern "C" with export.
I totally got lost in naming convention and mangling in C++. is related to local project setting or the dll will run on all environments? specially in this sample project how should I handle it?

build dlls using Visual Studio

I want to build dlls using Visual Studio which I want to use as functions in Matlab.
While doing so I have used declspec(dllimport) function...but I get compilation error LNK2019: unresolved external sumbol?
Appreciate your help.
#ifdef PRC50CONTROL_EXPORTS
#define PRC50CONTROL_API __declspec(dllexport)
#else
#define PRC50CONTROL_API __declspec(dllimport)
#endif
int PRC50CONTROL_API SetPRC50Gain(double inGain);
int PRC50CONTROL_API SetPRC50Gain(double inGain);
You have the return type before the __declspec()
Move it to
PRC50CONTROL_API int SetPRC50Gain(double inGain);
Also, obviously, make sure you have
PRC50CONTROL_EXPORTS
defined in your header of the library you're exporting the symbols from.

Using a non-COM object from a COM dll

A Visual Studio C++ solution is made of 2 projects both in C++:
Client produces a client.exe
Algo produces a algo.dll
Client and Algo communicate together via a COM Layer, hence Algo is a COM dll.
I want to add a function in Algo.dll and call it directly from Client, avoiding the COM Layer, but did not succeed to solve the "unresolved symbol" link errors when building the Client.exe
What was tried ?
In the Algo project, I've added the LIBRARY_EXPORT preprocessor definition and the following files:
TestFile.h
#ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
#else
# define LIBRARY_API __declspec(dllimport)
#endif
extern "C" LIBRARY_API bool __stdcall TestFunction();
TestFile.cpp
extern "C" LIBRARY_API bool __stdcall TestFunction()
{
return true;
}
In the client project, there is a call to TestFunction();
I get an link error when building the client:
unresolved external symbol "__declspec(dllimport) bool __cdecl TestFunction(void)
Apparently, I do not get correctly how to export/import my function.
You need to add algo.lib to the linker input files of client.exe

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