1

I am trying to use some software which has been written in C++ in a separate C program.

I have compiled the necessary components within a .lib file, and included some C code using

#ifdef __cplusplus
    extern "C" {
#endif

This code sort of wraps up the C++ object method calls within C callable functions. The objects are declared in file scope, and pointers to the objects are retreived initially and then later used to reference which object to call the method on. For example:

const void *GetHandle() {
    return (void *) &obj;
}

And then to call a method:

int GetInt(const void *handle) {
    Object *temp = (Object *) handle;
    return temp->getInt();
}

Is this a valid solution to the problem? At the moment, with just the GetHandle() methods in my C program, I get errors saying "error C2099: initializer is not a constant" when I try to assign their return values to some const void * variables.


EDIT

Fixed the problem. My ignorance of standard C bears itself here. I am used to Microchip C30 for dsPIC, which is a little different.

I was trying to both declare and initialize the pointers outside of any function. I did have them set as const but that's not really necessary, so I now just declare outside and then initialize in an init function. I also put extern "C" in front of all the functions in the cpp file, and it all compiles now. So, thanks to everyone for the help!

5
  • 1
    Did you mean to write #ifdef __cplusplus? Commented Aug 9, 2012 at 11:40
  • I don't know if this is the underlying issue, but remember MSVC is strictly C89 and all variable declarations/initializations need to be at the top of a block. Commented Aug 9, 2012 at 11:40
  • @rubenvb MSVC is "C89 with the C++ stuffs that are in C99". Commented Aug 9, 2012 at 11:51
  • That sounds like you might be trying to initialise a global variable with the result of a function call. You can do that in C++, but not in C. Although, without seeing the code that's causing the error, I can only guess what might be wrong. Commented Aug 9, 2012 at 12:17
  • @R.MartinhoFernandes not if you're compiling in C mode (which I think is active when the file extension is .c) Commented Aug 9, 2012 at 12:23

3 Answers 3

1

This is a valid solution.

You might want to check the constness of your argument/return values/casts more carefully though.

For example, if the object itself is not const, then GetHandle should return void *, not const void *. Same way, if getInt is a const function, then GetInt correctly gets a const void *. However, it should also cast it to const Object *, not Object *.

For further diagnosis, you should provide the exact line you get the initializer is not a constant error (and the context where the function is called). My guess is that the error is related to some other part of your code, using these incorrectly cast values.

Sign up to request clarification or add additional context in comments.

Comments

1

If I were you I would use the COM object to wrap all the C++ functionality please check this code project demonstration:

http://www.codeproject.com/Articles/13601/COM-in-plain-C

If you are not familiar with COM objects I think you can read this article first http://www.codeproject.com/Articles/633/Introduction-to-COM-What-It-Is-and-How-to-Use-It

2 Comments

There is so much more to COM that I'd think that the article you refer to is simply misleading. It tricks you into thinking that it presents the whole picture, that if you just follow it you'll get it right. That's not so. The article should come with a big fat warning: "This is only an introduction. You need to spend a couple weeks working through a good COM book to really figure things out. You have been warned". I think in this day and age COM is a technological dead-end and should not be used unless strictly necessary. A waste of time, so to speak.
I am implementing COM plugins for SharePoint 2010 in a commercial product. EMC and NetApp virus checking and online virus scanner use COM and RPC interfaces too!!! It is not dead but it is a little bit difficult. When I started working on COM and RPC I started by reading this book "Developer's Workshop to COM and ATL 3.0"
1

Your code have an error: you implicitly casting const void* handle to non-const Object* . Your approach is right - you should define all your wrapper function as extern "C" to force C-style linking, and also you must not forget about exceptions - you should catch them in wrappers to prevent them go through C stack.

1 Comment

There's no such thing as "implicit casting". Both casts are explicit, and use the C-style cast which allows any pointer conversion (including removing const qualifiers), so there's no compile-time error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.