Linking C/C++ and Fortran, unresolved external symbols - c++

My Visual studio 2010 solution file for a typical purpose consists of one fortran project (of static library type and consists of source1.f90), one C/C++ project(of application type and contains main.cpp) and 13 C/C++ project(of static library type and contains different .cpp/.h files for different classes). My purpose is to call the some of the functions in fortran source files from one of the C/C++ static library type project, But I am not able to build the program and am getting errors.
My first attempt was to call the fortran subroutine from main.cpp. But I am getting the following error:
Error 2 error LNK2019: unresolved external symbol "void __cdecl
bar_ftn(int,char *)" (?bar_ftn##YAXHPAD#Z) referenced in function _main
G:\VS2010\uakron\sourcefiles\application\main.obj
Error 3 error LNK1120: 1 unresolved externals G:\VS2010\uakron
\build\win\debug\application_app.exe 1
source1.f90
subroutine bar_ftn ( len_input_file, input_file ) bind( c )
use, intrinsic :: iso_c_binding, only : c_int
implicit none
integer(c_int), value, intent(in) :: len_input_file
character(len=1), intent(in) :: input_file(len_input_file)
! Local declarations (copy c char array into fortran character)
character(len=len_input_file) :: infile
integer :: i
print *, "in bar_ftn"
print *, len_input_file
do i=1,len_input_file
end do
end subroutine bar_ftn
main.cpp
#include<iostream>
#include<fstream>
using namespace std;
extern void bar_ftn ( int flag_len, char* flag );
static void
DisplayUsage(char* programName);
int main(int argc, char *argv[])
{
char ctext[]="helloworld abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz";
int ctext_len=sizeof(ctext);
//Call the Fortran
bar_ftn( ctext_len, ctext );
return 0;
}
On the other side, I also called the fortran function from one of the class functions from one of the C/C++ static library projects, but I am getting the same type of error (LNK2019).
Any help would be highly appreciated.

One issue is that you're declaring bar_ftn in C++, which results in name mangling, aka the odd ?bar_ftn##YAXHPAD#Z text you see in the error message. To avoid this, you'll need to prepend extern "C" before the function declaration:
extern "C" void bar_ftn ( int flag_len, char* flag ); // note that 'extern' by itself is unnecessary

Related

Trying to write a DLL for wallhack usw

I'm trying to write a DLL file that I can inject into a game. I'm pretty far but when I try to compile the code I always get the error
Error LNK2001 Unresolved external symbol "" unsigned char * __cdecl Detours :: X86 :: DetourFunction (unsigned char *, unsigned char *, enum Detours :: X86Option) "(? DetourFunction # X86 # Detours ## YAPAEPAE0W4X86Option # 2 ## Z ) ".
The detours folder I use is from here:
https://github.com/Nukem9/detours
but the Detours.h file was broken because I couldn't use uint8_t so I replaced the code in there with the code from that file:
https://github.com/Nukem9/VMWareClient/blob/master/vmware_client/detours/Detours.h
The codline where I think the problem is:
oEndScene = (EndScene)Detours::X86::DetourFunction((uint8_t*)d3d9Device[42], (uint8_t*)hkEndScene);
but for those who are interested, I can post the whole code here. Just tell me in the comments. The whole code is 256 lines long
You can't just replace function definition:
uintptr_t DetourFunction(uintptr_t Target, uintptr_t Detour, X86Option Options = X86Option::USE_JUMP);
with
uint8_t *DetourFunction(uint8_t *Target, uint8_t *Detour, X86Option Options = X86Option::USE_JUMP);
Why can't you use uint8_t? Can't you just add:
typedef unsigned char uint8_t;

Errors LNK 2019 and LNK2028 for one function in a class, other works fine

I normally work in c# and am out of my wits for this one . I used Walkthrough: Creating and Using a Dynamic Link Library (C++) to create a Dynamic Link Library.
I have defined two methods as shown below
DeveloperConsoleManager.h
#pragma once
#include "atlstr.h"
#ifdef DEVCONSOLEMANAGER_EXPORTS
#define DEVCONSOLEMANAGER_API __declspec(dllexport)
#else
#define DEVCONSOLEMANAGER_API __declspec(dllimport)
#endif
namespace DeveloperConsoleManager
{
class DeveloperConsoleLogic
{
public:
// Returns a + b
static DEVCONSOLEMANAGER_API double Add(double a, double b);
static DEVCONSOLEMANAGER_API bool CheckforValidFile(CString fileName);
};
}
DeveloperConsoleManager.cpp
// DeveloperConsoleManager.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "DeveloperConsoleManager.h"
namespace DeveloperConsoleManager
{
double DeveloperConsoleLogic::Add(double a, double b)
{
return a + b;
}
bool DeveloperConsoleLogic :: CheckforValidFile(CString fileName)
{
return false;
}
}
I use these methods in a .cpp file in a different project (type: Application (.exe)). When I Build the solution, there are following linker errors
Warning 1 warning C4273: 'DeveloperConsoleManager::DeveloperConsoleLogic::Add' : inconsistent dll linkage e:\md_69\developerconsolemanager\developerconsolemanager.cpp 10
Warning 2 warning C4273: 'DeveloperConsoleManager::DeveloperConsoleLogic::CheckforValidFile' : inconsistent dll linkage e:\md_69\developerconsolemanager\developerconsolemanager.cpp 16
Error 3 error LNK2028: unresolved token (0A0004F1) "public: static bool __cdecl DeveloperConsoleManager::DeveloperConsoleLogic::CheckforValidFile(class ATL::CStringT > >)" (?CheckforValidFile#DeveloperConsoleLogic#DeveloperConsoleManager##$$FSA_NV?$CStringT#_WV?$StrTraitMFC_DLL#_WV?$ChTraitsCRT#_W#ATL#####ATL###Z) referenced in function "public: void __thiscall CSaSsiConsoleUi::UploadSsiCheck(void)" (?UploadSsiCheck#CSaSsiConsoleUi##$$FQAEXXZ) E:\MD_69\DeveloperConsoleUI\SaSsiConsoleUI.obj
Error 4 error LNK2019: unresolved external symbol "public: static bool __cdecl DeveloperConsoleManager::DeveloperConsoleLogic::CheckforValidFile(class ATL::CStringT > >)" (?CheckforValidFile#DeveloperConsoleLogic#DeveloperConsoleManager##$$FSA_NV?$CStringT#_WV?$StrTraitMFC_DLL#_WV?$ChTraitsCRT#_W#ATL#####ATL###Z) referenced in function "public: void __thiscall CSaSsiConsoleUi::UploadSsiCheck(void)" (?UploadSsiCheck#CSaSsiConsoleUi##$$FQAEXXZ) E:\MD_69\DeveloperConsoleUI\SaSsiConsoleUI.obj
Error 5 error LNK1120: 2 unresolved externals E:\MD_69\Debug\DeveloperConsoleUi.exe
There is no linker error for the "Add" method.
I have already included "DeveloperConsoleManager.lib" in Linker -> Input -> Additional Dependencies. Please help me find out what exactly am I doing wrong.
I would be glad to add any additional information needed.
Thanks to #Igor Tandetnik and the awesome thing that is internet, I figured it out. I am adding it as an answer so that some one else might benefit.
The problem was with CString. The project in which the function was defined was a dynamic link library (dll) and the call was being made from an MFC application. Now, the issue was that, MFC uses for CString while the non-MFC dll uses .
CString in is defined as:
typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;
while in is defined as:
typedef CStringT< TCHAR, StrTraitATL< TCHAR > > CString;
This, as you can clearly see is different. The workaround I used was using CAtlString instead of CString . However, please feel free to suggest any better way if you come across.

Called C static library with everything wrapped in extern "C" and it's still not working [duplicate]

This question already has an answer here:
"undefined reference to" errors when linking static C library with C++ code
(1 answer)
Closed 6 years ago.
I'm calling a C static-link library in VS2010 by wrapping the header file with extern "C", but I'm still getting a LNK2001: unresolved external symbol. I'm calling the same .lib file somewhere else with no problems and I'm reusing old code from somewhere else that definitely works. The code I'm using can be found at github.com/toots/microsoft-audio-watermarking. I'm trying to use the "thrabs" function found in hthres.h. I can't think of any obvious reasons it's not working. Here's the example code. thrabs is the c external. Is it possible my variable _fm_lookup which is normally defined in C++ is the problem?
int i;
for(i = 0; i < NFREQ; i++)
_fm_lookup[i] = thrabs((0.5 + i) * (float) fs * 0.5 / (float) NFREQ);
the C static lib is being included by using
extern "C"
{
#include "htres.h"
}
the error is
Error 37 error LNK2001: unresolved external symbol _fm_lookup C:\Users\David\Documents\Projects\watermarking\Builds\VisualStudio2010\internal2003.lib(hthres.obj)
Needed to move the offending code into its own c file and call it from there while using extern "C". Painful lesson learned.

Conflict resolution using multiple static libraries in C++

I have 2 static libraries from «vendor1» and «vendor2»:
vendor1.lib and vendor1.h;
vendor2.lib and vendor2.h.
In the file, vendor1.h. The following declaration is there:
double Min();
In the file, vendor2.h. The following declaration is there:
double Min();
In my client file:
include "vendor1.h"
include "vendor2.h"
double x = Min();
It by defaults calls vendor1.h. I tried introducing the namespace:
namespace vendor1 {
include "vendor1.h"
}
namespace vendor2 {
include "vendor2.h"
}
A call to the following function
double xx = vendor2::Min();
I get the following linker errors:
Client.cpp 1>Client.obj : error LNK2019: unresolved external symbol "double __cdecl vendor2::Min(void)" (?Min#vendor2##YANXZ) referenced
in function _wmain 1>c:\temp\Client\Debug\Client.exe : fatal error
LNK1120: 1 unresolved externals
How can I fix this without creating wrappers for each of the wrappers?
If you have two static libraries with conflicting names you won't be able to link your program statically! The static linker will just go and find the first symbol matching an undefined symbol and choose this. Wrapping the names into a namespace doesn't help: this changes the namespace being expected in the library. You just found why namespace are a good thing.
How to solve the problem? I'm not aware of an approach which is based on the C++ standard. Practically, you may be able to do something: create a dynamic library which forwards to your conflicting functions but puts the name into separate namespaces (or uses different names). The dynamic libraries are linked with individual static libraries, i.e. the conflict doesn't happen at this time. You will probably also need to avoid the underlying names being visible from the symbols in the shared library. The details on how this is done depend on the compiler and I don't know who to deal with MSVC++ for things like this.
How about wrapping the functions into different namespaces?
vendor1_wrapper.h:
namespace vendor1 {
double Min();
}
vendor1_wrapper.cpp:
#include "vendor1_wrapper.h"
#include "vendor1.h"
namespace vendor1 {
double Min()
{
return Min();
}
}
vendor2_wrapper.h:
namespace vendor2 {
double Min();
}
vendor2_wrapper.cpp:
#include "vendor2_wrapper.h"
#include "vendor2.h"
namespace vendor2 {
double Min()
{
return Min();
}
}
Now you can use the functions using namespaces (your client file):
#include "vendor1_wrapper.h"
#include "vendor2_wrapper.h"
...
vendor1::Min();
vendor2::Min();

linking assembly and c problem

Trying to understand how to link a function that is defined in a struct, the function is in the assembly code, and am trying to call it from c. I think am missing a step cause when I call the function, I get an unresolved external symbol...
;Assembly.asm
.686p
.mmx
.xmm
.model flat
include Definitions.inc
.code
?Initialize#Foo##SIXPAUFee###Z proc
jmp $
?Initialize#Foo##SIXPAUFee###Z endp
end
//CFile.c
struct Fee
{
signed long id;
}
struct Foo
{
static void Initialize(Fee *);
}
int startup(Fee * init)
{
Foo::Initialize(init); //<-- This is unresolved
return 0;
}
Your assembly code defines a function whose decorated name decodes to
public: static void __fastcall Foo::InitializeCurrentCpu(struct Fee *)
As obtained through the undname.exe utility. Foo::InitializeCurrentCpu() won't be a match for Foo::Initialize(), the name doesn't match. Nor does the calling convention.
Write this code in C++ first and look at the .map file for the correct decorated name. Or declare the function with extern "C" to suppress C++ decoration.