Error C2059: syntax error : 'string' - c++

I have looked at other posts and to be honest I am still not sure what is causing the problem. I am programming in Visual Studio and
I have the following code: (this is a C main)
int main(int arc, char **argv) {
struct map mac_ip;
char line[MAX_LINE_LEN];
char *arp_cache = (char*) calloc(20, sizeof(char)); //yes i know the size is wrong - to be changed
char *mac_address = (char*) calloc(17, sizeof(char));
char *ip_address = (char*) calloc(15, sizeof(char));
arp_cache = exec("arp -a", arp_cache);
It uses the following cpp code:
#include "arp_piping.h"
extern "C" char *exec(char* cmd, char* arp_cache, FILE* pipe) {
pipe = _popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[128];
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL) {
strcat(arp_cache, buffer);
}
}
_pclose(pipe);
return arp_cache;
}
With the matching header file:
#ifndef ARP_PIPING_H
#define ARP_PIPING_H
#endif
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
#include <stdio.h>
#include <string.h>
extern "C" char *exec(char* cmd, char* arp_cache, FILE* pipe);
#undef EXTERNC
But I keep on getting the following errors:
1>d:\arp_proto\arp_proto\arp_piping.h(14): error C2059: syntax error : 'string'
1>main.c(22): warning C4013: 'exec' undefined; assuming extern returning int
1>main.c(22): warning C4047: '=' : 'char *' differs in levels of indirection from 'int'
Please can I get some help, I have looked at other posts regarding the c2059 but am still getting nowhere

Change your exec declaration to use the EXTERNC macro you have taken pains to define.
EXTERNC char *exec(char* cmd, char* arp_cache, FILE* pipe);

I ran into this compilation error when adding an enum to a project. It turned out that one of the values in the enum definition had a name clash with a preprocessor #define.
The enum looked something like the following:
// my_header.h
enum Type
{
kUnknown,
kValue1,
kValue2
};
And then elsewhere there was a #define with the following:
// ancient_header.h
#define kUnknown L"Unknown"
Then, in a .cpp somewhere else in the project, both of these headers were included:
// some_file.cpp
#include "ancient_header.h"
#include "my_header.h"
// other code below...
Since the name kUnknown was already #define'd, when the compiler came to the kUnknown symbol in my enum, it generated an error since the symbol was already used to define a string. This caused the cryptic syntax error: 'string' that I saw.
This was incredibly confusing since everything appears to be correct in the enum definition and compiles just fine on it's own.
It didn't help that this was in a very large C++ project, and that the #define was being transitively included in a completely separate compilation unit and was written by someone 15 years ago.
Obviously, the right thing to do from here is rename that terrible #define to something less common than kUnknown, but until then, just renaming the enum value to something else works as a fix, e.g.:
// my_header.h
enum Type
{
kSomeOtherSymbolThatIsntDefined,
kValue1,
kValue2
};
Anyway, hopefully this answer is helpful for someone else, since the cause of this error stumped me for a good day and a half.

extern "C" is used to tell the compiler to make it as C grammer, but your mean is to declear a extern function called exec. you just make fusion to the differ of this. so rewrite your code like this in arp_piping.h:
/*extern "C"*/ char *exec(char* cmd, char* arp_cache, FILE* pipe);
and then del the preffix of extern "C" in cpp file.
if you want to comiler them with C grammer, just setting in the cpp which call for the function exec, so write like this:
extern "C" {
#include "arp_piping.h"
}

Related

Conditional Compile of const static arrays

I am trying to create an error enum and associated text descriptors aligned in the same file. I have a system.cpp file that contains the following:
#define SYSTEMCODE
#include "myerrors.h"
The file myerrors.h contains:
typedef enum errors {
OK,
BADERROR,
LASTENUM } ERR;
#ifndef SYSTEMCODE
extern char const *_errtext[];
#else
const char * _errtext[ERR::LASTENUM +1] = {
"OK",
"BADERROR",
"LASTENUM" };
#undef SYSTEMCODE
#endif
I include system.h in all sources that need error services and they do not define SYSTEMCODE.
I expect that only the system.cpp file will compile the text array and all others will simply have an extern reference. The system.cpp object does not have the _errtext array thus causing a link error. I disable pre-compiled headers and I have tried many variations of this. MSDEV does not get it right.
Any ideas?
Usually, in all the projects I've worked I have seen it done this way.
Create a file myerror.h:
#ifndef _MYERROR_H__
#define _MYERROR_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef enum errors {
OK,
BADERROR,
LASTENUM
} ERR;
extern const char *err_msg(ERR err);
#ifdef __cplusplus
} // extern C
#endif
And then a file myerror.cpp:
#include "myerror.h"
static const char *_errtext[] = {
"OK",
"BADERROR",
"LASTENUM"
};
const char* err_msg(ERR error){
return _errtext[error];
}
That way you just have to include myerror.h from all the files you want and call err_msg(error) whenever you want to print the error in text format. So in another file you'd have:
#include "myerror.h"
int method(){
ERR whatever = OK;
std::cout << err_msg(whatever);
... // Some other stuff here
}
I'm not sure why you want it done in the same file, but as I said, this is how I usually see it done.

Syntax error C2059 when building building C application using C/C++ DLL header

I'm attempting to translate a C++ DLL header file into a C/C++ compatible header. While I've gotten most of the major constructs in, I'm running into one last compiler issue I can't seem to explain. The following code works fine in C++ but when I attempt to compile a C application which just includes this file I get errors for my function definitions in my header file.
Code.h:
typedef void *PVOID;
typedef PVOID HANDLE;
#define WINAPI __stdcall
#ifdef LIB_EXPORTS
#define LIB_API __declspec(dllexport)
#else
#define LIB_API __declspec(dllimport)
#endif
struct ToolState
{
HANDLE DriverHandle;
HANDLE Mutex;
int LockEnabled;
int Type;
};
#ifdef __cplusplus
extern "C" {
#endif
(LIB_API) int SetRate(ToolState *Driver, int rate);
(LIB_API) void EnableLock(ToolState *Driver) ;
(LIB_API) int SendPacket(ToolState *Driver, unsigned char *OutBuffer, int frameSize);
//These also give me the same error:
//LIB_API WINAPI int SendPacket(ToolState *Driver, unsigned char *OutBuffer, int frameSize);
//__declspec(dllimport) WINAPI int SendPacket(ToolState *Driver, unsigned char *OutBuffer, int frameSize);
//Original C++ call that works fine with C++ but has multiple issues in C
//LIB_API int SetRate(ToolState *Driver, int rate);
#ifdef __cplusplus
}
#endif
Errors:
error C2059: syntax error : 'type'
error C2059: syntax error : 'type'
error C2059: syntax error : 'type'
Google searching hasn't generated any relevant results. The following threads were close but don't exactly answer my question:
C2059 syntax error using declspec macro for one function; compiles fine without it
http://support.microsoft.com/kb/117687/en-us
Why is this syntax error occuring?
In C, structs are not types, so you must use struct Foo and enum Bar where in C++ you are able to use Foo and Bar.
Notes:
In C++, you can still use the old syntax even when the type is a class.
In C, people often use typedef struct Foo Foo which allows the same syntax as in C++ then.

error C2062 when compiling

first I want to say that i'm totally a noob in C or C++. I'm trying to understand how compiling works, how the language works etc. This time I've been looking for a solution for many hours before posting here. I hope you will be able to help me, even if it appears to be a very easy findable solution.
Here it is.
I'm trying to nmake a makefile.Win32 file and I got these errors :
e:\progs\c\vanitygen-master\winglue.h(47) : error C2062: type 'char' unexpected
e:\progs\c\vanitygen-master\winglue.h(47) : error C2143: syntax error : missing ';' before '{'
e:\progs\c\vanitygen-master\winglue.h(47) : error C2447: '{' : missing function header (old-style formal list?)
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\cl.EXE"' : code retour '0x2'
Stop.
Here is the winglue.h file (--> points the line 47)
#include <windows.h>
#include <tchar.h>
#include <time.h>
#define INLINE
#define snprintf _snprintf
struct timezone;
extern int gettimeofday(struct timeval *tv, struct timezone *tz);
extern void timeradd(struct timeval *a, struct timeval *b,
struct timeval *result);
extern void timersub(struct timeval *a, struct timeval *b,
struct timeval *result);
extern TCHAR *optarg;
extern int optind;
extern int getopt(int argc, TCHAR *argv[], TCHAR *optstring);
extern int count_processors(void);
#define PRSIZET "I"
static inline char *
/* --> */ strtok_r(char *strToken, const char *strDelimit, char **context) {
return strtok_s(strToken, strDelimit, context);
}
#endif /* !defined (__VG_WINGLUE_H__) */
I hope you guys will help me !
I'm using Visual Studio C++ 2010 Express on a Win 7 64bits computer.
Edit : If it helps to know it, I'm running a brand new installation of the software.
The simple fix is to make it a define, you are calling a different function with the same parameters in the same order, returning the result.
But as to the cause of your problem, its probalbly a stupid define in <windows.h>, it has alot of defines it shouldnt. Im guessing its inline. try __inline__ instead.

Calling C++ function from a C code

So I have looked here and here and at a few other links mentioned in the first question and I have the following code already:
The .cpp file:
#include "arp_piping.h"
#include <string>
#include <iostream>
#include <stdio.h>
std::string exec(char* cmd, FILE* pipe) {
pipe = _popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[128];
std::string result = "";
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
_pclose(pipe);
return result;
}
The header/linker file:
#ifndef ARP_PIPING_H
#define ARP_PIPING_H
#endif
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
my function goes here something like
EXTERNC .....exec(char* cmd, FILE* pipe) ????
#undef EXTERNC
My question is what goes in the bit above as I am unsure what to be typing. I am trying to call the function in the .cpp file from my C main function int main(int argc, char** argv) {}
To call C++ functions from C you need to do two things. 1) Let the C++ code know it's going to be used by C so that it can generate C-friendly symbols. 2) Hide any functionality that C can't understand.
The first part is easily achieved by simply defining the functions as you would in C (I.E. don't use any C++ only features like namespaces) and then wrapping them in an extern "C" block if C++ is defined. You basically want your header file to contain C-only code, and then just open the extern block at the top, and close it at the bottom of the file (my example will make this more clear).
The second part is a little trickier, but not too difficult. In your case, your function returns a std::string which is a C++ only class. It can not be used in C and therefore either needs to be replaced with something that can be used in C, or it needs to be hidden behind something that C can use. For the sake of argument let's assume you can't replace std::string with say, char*. In this case you need to hide std::string from the C-facing code. The common way of doing this is to use an opaque pointer.
Basically, the C-facing code deals only with a pointer to something. That something it neither knows about, nor cares about. The C++ code is free to use a std::string internally, but must make sure to hide it before interfacing with the C API. In my example, you can see I've provided an opaque pointer to a struct I've called cppstring.
In the source file, cppstring is just a struct that holds a std::string. I've changed your example code to use the new cppstring struct. One important thing to note is that because the C code can only deal with a pointer to a cppstring, we need to create it on the heap in our C++ code and return the pointer to it. This means that we must provide the C users some way of freeing it when they're done, which I've also provided in the example.
Using this technique you can wrap the entirety of std::string behind a C API, allowing C users to use all of the functionality that std::string provides. I've provided an example of wrapping std::string::substr to show you how.
N.B. I haven't compiled nor tested this code and for the sake of simplicity I haven't included any of the relevant header files, etc. Nevertheless, it should be enough to get you started.
// C header
#ifdef __cplusplus
extern "C" {
#endif
typedef struct cppstring *cppstring_p;
cppstring_p exec(char *cmd, FILE *pipe);
void free_cppstring(cppstring_p cppstr);
/* example of wrapping std::string::substr for C users */
cppstring_p substr(cppstring_p str, int pos, int count);
#ifdef __cplusplus
}
#endif
// CPP source
struct cppstring {
std::string data;
cppstring(void) {}
cppstring(std::string const& s) : data(s) {}
};
cppstring_p exec(char *cmd, FILE *pipe) {
pipe = _popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[128];
auto result = new cppstring;
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result->data += buffer;
}
_pclose(pipe);
return result;
}
void free_cppstring(cppstring_p cppstr) {
delete cppstr;
cppstr = nullptr;
}
cppstring_p substr(cppstring_p str, int pos, int count) {
assert(str);
return new cppstring(str->data.substr(pos, count));
}
You need to declare the function as extern "C" in the cpp file:
extern "C" char *exec(char* cmd, FILE* pipe) {
...
}
In the header/linker file you need to declare it's prototype with the keyword "extern", like so:
extern char *exec(char* cmd, FILE* pipe);
Also, are you sure you want to return a c++'s std::string to your C code?

Use bison and flex with vc6

When i use bison & flex with vc6, i got got below errors
lex.yy.c(395) : error C2146: syntax error : missing ';' before identifier 'YY_PROTO'
lex.yy.c(395) : fatal error C1004: unexpected end of file found
what would be the cause for this??
please help.
Copied from Comment:
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
extern "C" int yywrap YY_PROTO(( void ));
#else
extern int yywrap YY_PROTO(( void ));
#endif
#endif
The YY_PROTO macro is only to support old pre-standard C without support for prototypes. You will have hard to find a compiler that does not support that today. That means that as a first debugging step you could try to remove it completely since you want to use prototypes, i.e. modify lex.yy.c to the following:
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
extern "C" int yywrap ( void );
#else
extern int yywrap ( void );
#endif
#endif
I know that lex.yy.c is a generated file, so that will not be a permanent fix, but it should at least confirm that the problem is related to the definition of YY_PROTO.
YY_PROTO is a macro that is defined earlier in the same file, so something odd is going on near the macro definition. Search earlier in the file to see how YY_PROTO is defined -- if its not getting defined, your compiler is doing something very weird.