In my project there are 3 possible types of files: pure C/Objective-C, pure C++ or Objective-C++ code.
How to divide functions in .h file with #define directives into parts to make this file available for all these files? I don't want to rename all the .m files to .mm because of problems with refactoring.
I know that I can write .h file in C which uses C++ .cpp file using the following code:
#ifndef Chadstone_CCCWrapper_h
#define Chadstone_CCCWrapper_h
#ifdef __cplusplus
#include <string.h>
extern "C"
{
#endif
void minMaxCoordinates(char *c, float *minX, float *minY, float *maxX, float *maxY);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif
but what if I want to add functions with using of NSString or list<...>.
You can find it in standard pch-file genarated by Xcode:
#ifdef __OBJC__
#endif
Also you need use CF_EXPORT macro when declaring function to prevent linkage errors.
Example:
#ifndef SOME_H_FILE
#define SOME_H_FILE
#ifdef __OBJC__
#interface SomeObjClass: NSObject
#end
CF_EXPORT void SomeFunctionWithNSString(NSString* str);
#endif
#ifdef __cplusplus
class SomeCPlusPlustClass
{
};
CF_EXPORT void someFunctionWithList(const list<int>& intList);
#ifdef __OBJ__
CF_EXPORT void someComplicatedFunction(NSString* str, const list<int>& intList);
#endif
#endif
CF_EXPORT void someFunction();
typedef struct _SomeStruct
{
} SomeStruct;
#endif
Related
I have a very basic example of the task I'm trying to solve. From the main loop in arduino.ino I call the sample_run() function in device.c using the definition in sample.h. From here I'm trying to understand how I can use the GPIO pins from device.c. Can this be done using the arduino ide? I've attached some sample code of what I'm trying to do.
arduino.ino
#include "sample.h"
#include "esp8266/sample_init.h"
void setup() {
}
void loop() {
sample_run();
}
sample.h
#ifndef SAMPLE_H
#define SAMPLE_H
#ifdef __cplusplus
extern "C" {
#endif
void sample_run(void);
#ifdef __cplusplus
}
#endif
#endif /* SAMPLE_H */
device.c
#include "sample.h"
void sample_run(void)
{
//I would like to turn on/off led here
}
In device.c: #include "Arduino.h"
Why are you using .c files and not .cpp?
I have a header file and its cpp file (Error.h, Error.cpp). The cpp file performs a check on a preprocessor directive but it always fails.
Error.h:
/*
Optional macros:
AE_EXIT_AT_ERROR
AE_CONSOLE_WRITE_AT_ERROR
*/
#pragma once
extern void aeError(const char *str, int code=1);
extern void aeAssert(bool b, const char *failStr = "assertion failed");
Error.cpp:
#include "Error.h"
#include <stdexcept>
#ifdef AE_CONSOLE_WRITE_AT_ERROR
#include <iostream>
#endif
void aeError(const char *str, int code)
{
#ifdef AE_CONSOLE_WRITE_AT_ERROR
std::cout << str << std::endl;
#endif
throw std::runtime_error(str);
#ifdef AE_EXIT_AT_ERROR
std::exit(code);
#endif
}
void aeAssert(bool b, const char *failStr)
{
if(!b)
aeError(failStr);
}
main.cpp:
//define both macros:
#define AE_CONSOLE_WRITE_AT_ERROR
#define AE_EXIT_AT_ERROR
#include "Error.h"
//rest of code
//...
both std::cout << str << std::endl; and std::exit(code); don't get compiled (I checked it "manually", although they are also marked gray by the IDE, which is VS2010).
What might be the cause of this?
main.cpp and Error.cpp are different translation units. You define the macro only for main.cpp, not for Error.cpp.
You should either put your #define directives in a header file included by both .cpp files, or define these macros in project settings/makefile.
Instead of writing each function in " extern "C" {} ", can I write entire header file inside that block.
extern "C"
{
#include "myCfile.h"
}
I have tried this but Its not working at all, why it is not working ?
if we have to use 100 C functions in a c++ project, do we need provide all the functions in a
extern block, is there any other simple way ?
Ex:
extern "C"
{
void fun1();
void fun2();
void fun3();
void fun4();
void fun5();
.
.
.
.
fun100();
}
Is there any other simple way, like extern "C" { myCfunctions.h } ???
#include simply includes the specified header at the location of the #include. Whether it's valid depends on what "myCfile.h" contains. In particular, including any standard library headers in such a context is not valid, and may well break on commonly used implementations.
The usual way to handle this is to make the header itself safe to use from C++. A C-only header might contain
#ifndef H_MYCFILE
#define H_MYCFILE
#include <stddef.h>
void mycfunc1(void);
void mycfunc2(int i);
void mycfunc3(size_t s);
#endif
Adapting this to make it safe to use from C++:
#ifndef H_MYCFILE
#define H_MYCFILE
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void mycfunc1(void);
void mycfunc2(int i);
void mycfunc3(size_t s);
#ifdef __cplusplus
}
#endif
#endif
With such a header, you wouldn't be able to safely put the entire header in an extern "C" block. However, that header itself can make sure not to put #include <stddef.h> in an extern "C" block, but still to put all function declarations in a single extern "C" block, avoiding having to repeat it for each one.
You are doing something wrong.
Because
extern "C" { myCfunctions.h }
should work. See below sample program.
Lets go by example code.
ctest1.c
#include<stdio.h>
void ctest1(int *i)
{
printf("This is from ctest1\n"); // output of this is missing
*i=15;
return;
}
ctest2.c
#include<stdio.h>
void ctest2(int *i)
{
printf("This is from ctest2\n"); // output of this is missing
*i=100;
return;
}
ctest.h
void ctest1(int *);
void ctest2(int *);
Now lets make c library from that
gcc -Wall -c ctest1.c ctest2.c
ar -cvq libctest.a ctest1.o ctest2.o
Now lets make cpp based file which will use this c apis
prog.cpp
#include <iostream>
extern "C" {
#include"ctest.h"
}
using namespace std;
int main()
{
int x;
ctest1(&x);
std::cout << "Value is" << x;
ctest2(&x);
std::cout << "Value is" << x;
}
Now lets compile this c++ program with C library
g++ prog.cpp libctest.a
Output is :
Value is15Value is100
I have a .lib which has a function that I want to make into a DLL.
In the project properties, I have done 2 things,
1. In the C/C++ -> General -> Additional Directories: added the path for the .h file.
2. In the Linker-> General -> Additional Dependies: added the path for the .lib file
Then I made an .h file
#ifndef _DFUWRAPPER_H_
#define _DFUWRAPPER_H_
#include <windows.h>
#include "DFUEngine.h"
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void helloworld(void);
__declspec(dllexport) void InitDLL();
#ifdef __cplusplus
}
#endif
#endif
and made the .cpp file
#include "stdafx.h"
#include "stdio.h"
#include "DFUWrapper.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
void helloworld(void)
{
printf("hello world DFU");
}
DFUEngine* PyDFUEngine()
{
return new DFUEngine();
}
void delDFUEngine(DFUEngine *DFUe)
{
DFUe->~DFUEngine();
}
void PyInitDLL(DFUEngine *DFUe)
{
return DFUe->InitDLL();
}
I made a test with the function helloword. I can see this function in the DLL but not the InitDLL function.
How can I come around this? Please help
Define the following in your DLL header file
#if defined (_MSC_VER)
#if defined (MY_DLL_EXPORTS)
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT __declspec(dllimport)
#endif
#else
#define MY_EXPORT
#endif
Declare your function using that macro
#ifdef __cplusplus
extern "C" {
#endif
MY_EXPORT void helloworld(void);
MY_EXPORT void InitDLL();
#ifdef __cplusplus
}
#endif
And in your .cpp
MY_EXPORT void helloworld(void)
{
printf("hello world DFU");
}
MY_EXPORT void InitDLL()
{
/// blahblah
}
Compile your DLL with MY_DLL_EXPORT defintion....
But be sure that it's not define when you want IMPORT ....
I like exporting functions from DLLs using .DEF files.
This has the added benefit of avoiding name mangling: not only the C++ complex mangling, but also the one happening with __stdcall and extern "C" functions (e.g. _myfunc#12).
You may want to simply add a DEF file for your DLL, e.g.:
LIBRARY MYDLL
EXPORTS
InitDLL #1
helloworld #2
... other functions ...
I would like to include one header file in both C and C++, and I have a function defined in C code and few functions defined in external library.
#if defined(__cplusplus)
extern "C" {
#endif
void func0();
#if !defined(__cplusplus)
extern {
#endif
void func1();
int func2(int);
} /* extern */
This code produces compilation error when compiled from C source file
error C2059: syntax error : '{'
Is it possible to fix syntax error directly or I have to use some macros?
EXTERNCPP void func0();
EXTERNC void func1();
EXTERNC int func2(int);
Edit 1:
I do not ask about
Effects of the extern keyword on C functions, I just ask if it is possible to fix syntax in easy way. If it is not possible, i could still remove it completely for C part
Edit 2:
To clarify what I want to get. If header is included
from C++:
extern "C" void func0();
extern "C" void func1();
extern "C" int func2(int);
from C:
void func0();
extern void func1();
extern int func2(int);
extern { is not needed.You need to remove it:-
#if defined(__cplusplus)
extern "C" {
#endif
void func0();
#if !defined(__cplusplus)
#endif
void func1();
int func2(int);
#if defined(__cplusplus)
}
#endif
You can simply omit the extern { line when compiling as a C header.
#if defined(__cplusplus)
extern "C" {
void func0();
#endif
#if !defined(__cplusplus)
void func1();
int func2(int);
#endif
#if defined(__cplusplus)
}
#endif
* [EDIT] answering your last edit:
void func0(); /* included in both versions */
#if defined(__cplusplus)
extern "C" {
void func1();
int func2(int);
#endif
#if !defined(__cplusplus)
extern void func1();
extern int func2(int);
#endif
#if defined(__cplusplus)
}
#endif
If you want to use func0 as extern in C:
#if defined(__cplusplus)
extern "C" {
void func0();
void func1();
int func2(int);
#endif
/* C block */
#if !defined(__cplusplus)
extern void func0();
extern void func1();
extern int func2(int);
#endif
#if defined(__cplusplus)
}
#endif
If you don't want to use it at all (from C) remove it from the C block