hej.h
void hej();
hej.m
void hej(){}
main.mm
#import "hej.h"
int main(int argc, char *argv[])
{
}
This gives me:
"hej()", referenced from:
_main in main.o
symbol(s) not found
If I rename main.mm to main.m (single m), or hej.m to mm or cpp, then it works. (Though none of those "solutions" are preferable. Imagine you want to use a c-lib in a objc++ environment - you wouldn't wanna change the entire lib, maybe even couldn't, and you need to use it in objc++.)
What exactly is going on here?
When compiled in a C file (*.c, *.m), the declaration void hej() generates a linker reference to a C function named _hej. When compiled in a C++ file (*.cc, *.mm, etc.), the declaration generates a linker reference to a C++ 'mangled name', that includes in it a description of the arguments. (This is done to support function overloading, e.g. to differentiate void hej(int) from void hej(char*)). hej.m always creates the C name. When main.mm references the C++ name, it won't be found.
To resolve, ensure main.mm looks for a C name, not a C++ one. If you control hej.h, it's common to add something like the following, which would work when hej.h is included in either a C or a C++ file:
/* hej.h */
#ifdef __cplusplus
extern "C" {
#endif
void hej();
#ifdef __cplusplus
}
#endif
If you do not own hej.h, you could do the following in main.mm instead:
extern "C" {
#import "hej.h"
}
int main(int argc, char *argv[])
{
}
Related
screenshot of my code and error data
This is my main.c file
#include "services_initialisations_prototype.h"
#include "services_functions_prototype.h"
void main(void)
{
initSfr();
while(1){
updateMatrix(404, 1);
}
return;
}
this is my services_initialisations_prototype.h
#ifndef XC_HEADER_TEMPLATE_H
#define XC_HEADER_TEMPLATE_H
#include <xc.h> // include processor files - each processor file is guarded.
#include <stdint.h>
//these are my function declarations
extern void initInterrupt();
extern void initIoc();
extern void initAdc();
extern void initTimer2();
extern void initSfr();
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XC_HEADER_TEMPLATE_H */
this is my services_functions_prototype.h
#ifndef XC_HEADER_TEMPLATE_H
#define XC_HEADER_TEMPLATE_H
#include <xc.h> // include processor files - each processor file is guarded.
#include <stdint.h>
//these are my function declarations
extern void updateMatrix(int, int);
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XC_HEADER_TEMPLATE_H */
When I try to include two header files in MPLAB X IDE version 4.05, it seems like it is not identifying the second header file. i tried swapping the order, but still the second one is not detected.
The services_initialisation_prototype.h contains initialisations of SFRs and services_functions_prototype.h contains prototypes of other functions. these functions are independent of each other.
when i compile, it is showing that
function updateMatrix() is declared as implicit int.
conflicting declarations for variable _updateMatrix()
which shows that the header file services_functions_prototype is not identified.
the screenshot attached shows the code in services_functions_prototype.h in grey color, and it seems that part of code is not executed.
When I copied the whole declarations from header file to my main file, it is working perfectly fine.
You used the same include guard in both files. Because one file is included before the other, it defines XC_HEADER_TEMPLATE_H which makes #ifndef fail in the second file. Change them to something unique. Wiki include guard.
Remember that identifiers with two leading underscores or identifiers with a leading underscore and an upper case letter are reserved by C standard. Good documentation online is in gcc reserved names.
Use filename with uppercase like SERVICES_FUNCTIONS_PROTOTYPE_H_ and SERVICES_INITIALIZATIONS_PROTOTYPE_H_.
Notes:
Empty parameter list in function declaration declares a function that takes unknown count and type of parameters. Prefer explicitly writing void inside function parameter list to define a function that takes no argument, to enable compiler static checking. Ie. do void initInterrupt(void);. cppreference function declaration
Identifiers declared at file scope are implicitly with external linkage. Ie. externis just redundant., just void initSfr(void); instead of extern void initSfr(); cppreference storage-class
The extern "C" { part makes no sense in your headers - there is nothing inside it. It's typicall to put extern "C" { on top of the header file to include everything inside. If your headers would be used by a C++ compiler, the functions names would be mangled and not properly resolved. I believe I would suggest to just remove the extern "C" { part.
Im trying to write a wrapper in c++/cli for an DLL, which code i dont have, only DLL file and header but i created lib file through VS command prompt. When i`m trying to build solution i receive this errors:
DotNetWrappOfAsterSdkDll.obj : error LNK2028: unresolved token (0A00002E) "void __stdcall MuteClearLastError(void)" (?MuteClearLastError##$$FYGXXZ) referenced in function "public: void __clrcall DotNetWrappOfAsterSdkDll::WrapperClass2::doMuteClearLastError(void)" (?doMuteClearLastError#WrapperClass2#DotNetWrappOfAsterSdkDll##$$FQ$AAMXXZ)
DotNetWrappOfAsterSdkDll.obj : error LNK2019: unresolved external symbol "void __stdcall MuteClearLastError(void)" (?MuteClearLastError##$$FYGXXZ) referenced in function "public: void __clrcall DotNetWrappOfAsterSdkDll::WrapperClass2::doMuteClearLastError(void)" (?doMuteClearLastError#WrapperClass2#DotNetWrappOfAsterSdkDll##$$FQ$AAMXXZ)
I tried to create my own DLL and include it to the wrapper, and its working perfectly
here dll created by me which i can use in c++/cli wrapper:
//header file
#pragma once
#define DLLEXP __declspec( dllexport )
namespace Computations {
DLLEXP void someMethod(int number);
}
//cpp file
#include "Computations.h"
#include <iostream>
#include <time.h>
//#include "pnl/pnl_random.h"
using namespace std;
void Computations::someMethod(int number)
{
std::cout << "something "<<number*number << endl;
}
and here is part of header of DLL which i want to use:
#ifndef MUTEIFC_H
#define MUTEIFC_H
#include <Windows.h>
#ifdef MUTEIFC_LIBRARY
# define MUTEAPI extern "C"__declspec(dllexport)
#else
# define MUTEAPI __declspec(dllimport)
#endif
#define MUTECALL __stdcall
/** \ingroup init */
/** Initialization of the ASTER SDK library
* \returns TRUE - success, FALSE - failure (use \ref MuteLastErrorCode or/and \ref MuteLastErrorInfo to get
* failure cause)
* \note This function will require Administrative privileges on the first call on a given computer.
*/
MUTEAPI BOOL MUTECALL MuteIfcInitialize(VOID);
/** \ingroup init */
/** Finialization of the ASTER SDK library
*/
MUTEAPI VOID MUTECALL MuteIfcFinalize(VOID);
/** \ingroup errors*/
/** Clears the calling thread's last-error code and description.
* The last-error is maintained on a per-thread basis. Multiple threads do not overwrite each other's last-error.
*/
MUTEAPI VOID MUTECALL MuteClearLastError(VOID);
#endif // MUTEIFC_H
and my c++/cli code :
//header file
#pragma once
#include "Computations.h"
#include "muteifc.h"
using namespace System;
namespace DotNetWrappOfAsterSdkDll
{
public ref class WrapperClass2
{
public:
void doMuteClearLastError();
};
public ref class WrapperClass
{
private:
public:
void getPriceCallEuro(int number);
};
}
//cpp file
#include "DotNetWrappOfAsterSdkDll.h"
using namespace DotNetWrappOfAsterSdkDll;
using namespace Computations;
namespace DotNetWrappOfAsterSdkDll
{
//this dont work
void WrapperClass2::doMuteClearLastError() {
MuteClearLastError();
}
//this works great
void WrapperClass::getPriceCallEuro(int number) {
someMethod(number);
//MuteIfcFinalize();
}
}
Please tell me what i'm doing wrong
You probably didn't add the lib that contains the function reference to the linker options.
Either the lib contains he code it self or it has a reference to the DLL that must be loaded. The linker will bring your code and the DLL (or static lib) code together...
How can I use functions from my file.c in Objective C
I tried #include < file.c > in file2.m where I want to call this functions and got Lexical or Prepocesor Issue < file.c > not found and when I use #include "file" i got Apple Mach-O Linker (ID) Error. Same errors when I use #import instead of #include.
If in "file.m" you have a function like this:
void hello()
{
printf("Hello world!");
}
You also have to create a header file possibly called "file.h" in which you only declare the function but don't actually implement it;
void hello();
Then you have to #import or #include thw file.h file from file2.m.
Does your file.c have a file.h with the function declarations? You will want to #include that, and also make sure that file.c is compiled and linked in.
I've got a weird linker issue. I have code that looks like so:
double given_amount = self.modelController.levelCompleteRewardAmount;
swrve_currency_given(swrve, (CFStringRef)#"currencyName", given_amount);
I have this code in two separate places: In an objective-c and an objective-c++ file. It compiles fine in objective-C land, but the swrve_currency_given() function causes the following in my WGController.mm file:
Undefined symbols for architecture armv7:
"swrve_currency_given(Swrve*, __CFString const*, double)", referenced from:
-[WGController giveTheUserSomeCashForPlayingThisLevel] in WGController.o
ld: symbol(s) not found for architecture armv7
collect2: ld returned 1 exit status
I'm not entirely sure if this error is related to the Obj-C vs. C++ thing, but it feels like it. My theory is that it perhaps thinks that it is a function on the Obj-C class? The 'swrve' code is 3rd party code, one .h and .c file and I'm importing like so:
#import "swrve.h"
Any help is appreciated!
Thanks
You may need to surround the function prototype with:
#if defined __cplusplus
extern "C" {
#endif
void swrve_currency_given (...whatever goes here...);
#if defined __cplusplus
};
#endif
That tells the compiler that it's a C function and not a C++ function.
If you are using c function in c++ file. you should use extern "c"{}.
In .h file
#ifdef __cplusplus
extern "C" {
#endif
swrve_currency_given(parameter1, parameter2, parameter3);// a c function
#ifdef __cplusplus
}
#endif
extern "C" is meant to be recognized by a C++ compiler and to notify
the compiler that the noted function is (or to be) compiled in C
style.
If you're linking to a library that was compiled as C code. use
extern "C" {
#include "c_only_header.h"
}
Take a look at When to use extern "C" in C++?
I made a DLL with a function named "render()" and I want to load it dynamically to my application, but GetProcAddress cannot find it. Here's the DLL .h:
#ifdef D3D_API_EXPORTS
#define D3D_API_API __declspec(dllexport)
#else
#define D3D_API_API __declspec(dllimport)
#endif
D3D_API_API void render();
And here's DLL .cpp:
#include "stdafx.h"
#include "D3D_API.h"
#include <iostream>
D3D_API_API void render()
{
std::cout << "method called." << std::endl;
}
Here's the application that tries to use that function:
#include "stdafx.h"
#include <windows.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE myDLL = LoadLibrary( L"D3D_API.dll" );
if (myDLL == NULL) {
std::cerr << "Loading of D3D_API.dll failed!" << std::endl;
}
typedef void (WINAPI *render_t)();
render_t render = (render_t)GetProcAddress( myDLL, "render" );
if (render == NULL) {
std::cerr << "render() not found in .dll!" << std::endl;
}
return 0;
}
My goal is to make a 3D engine that supports both D3D and OpenGL through their own .DLLs using a unified API. I looked at the .dll in notepad and there was a string "render".
The function you export is treated as a C++ function (because of *.cpp file extension) and so C++ name mangling is used to decorate the exported function name. If you use the Dependency Walker tool from Microsoft to inspect your created DLL you will see the functions full name.
You can either use that decorated name in your import code or force the compiler to export your function in C style, that is, in its undecorated form that your current import code expects.
You can tell the compiler to do so by adding extern "C" to your functions signature. Something like this:
extern "C" D3D_API_API void render();
Now your import code should work as expexted.
As the comment to the answer says:
using 'extern "C"' will remove any C++ name mangling, but still leaves
C name mangling. In order to export the plain names you should look at
using a .DEF file. See
blogs.msdn.microsoft.com/oldnewthing/20120525-00/?p=7533
You need to add a new file with .DEF extension to your project, with similar to this contents:
LIBRARY "MyRenderLib"
EXPORTS
render
Then in your DLL header you don't use __declspec(dllexport), but only extern "C"
extern "C" void render();