Second C Linkage in shobjidl.h - c++

I am currently moving a C++ project from VS6 to VS2008, but I have come accross the following error for many of the functions in shobjidl.h
error C2733: second C linkage of overloaded function 'HWND_UserMarshal' not allowed c:\program files\microsoft sdks\windows\v6.0a\include\shobjidl.h 28830
Not just HWND_UserMarshall is affected, also other functions in this header, such as HWND_UserSize, HWND_UserFree and HWND_UserFree64.
I understand that this error occurs when an extern "C" function is declared with a different set of parameters, however this is in a SDK header, not one that I can change.
Does anyone have any suggestions of what my next steps should be?
EDIT: The header is a Microsoft header and at the top contains the following comments
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* File created by MIDL compiler version 7.00.0499 */
/* Compiler settings for shobjidl.idl:
Oicf, W1, Zp8, env=Win32 (32b run)
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
//##MIDL_FILE_HEADING( )

Unfortunately, I'm not familiar with this header or these functions. However, I suspect that there are C macros meant to control which functions are visible to you based on preprocessor defines. And I suspect that you somehow have defined (or not defined) preprocessor symbols in a way that you're getting duplicate function definitions.
Not being familiar with the header, I can't really recommend what to do to get just the functions you want. I would probably start by reading the documentation, looking at the configuration for similar products, and reading the header file itself.

Are those headers generated from an IDL file? If so you probably need to re-generated them using a VS2008 compliant tool.
For example if you are using the TAO ORB you would download the latest version (or the 2008 version) and run the tool:
tao_idl -Cw -GT shobjidl.idl
Using appropriate flags and paths.
EDIT: From your update it does seem like you are meant to generate this file. MIDL is the Microsoft IDL compiler. Check the docs on MSDN for info on the compiler: http://msdn.microsoft.com/en-us/library/windows/desktop/aa367300%28v=vs.85%29.aspx

Related

BOOL redefinition after including minwindef.h

I am a newbie in C/C++, just in case :)
I have cloned an older protocol stack solution written in C with one main class in C++ imported it into VS
(Visual C++ 2017 v 15.9.5 targeting Windows SDK 10.0.17134.0) it compiled correctly and working.
Now made a C++ solution (windows console application) created a folder lib copy pasted all those .h and .c files into lib added the path to additional include directories and also in linker additional library directories.
Building the Solution throwing tones of errors. the one I am trying to fix now is:
One of the header files contains type definitions
typedef uint8_t U8;
#ifndef BOOL
typedef U8 BOOL;
#endif
but this is conflicting with minwindef.h from windows kit. though I #include types.h getting C2371 'BOOL': redefinition; different basic types
in the whole solution, I want to use this definition of BOOL and all other ones defined in this header.
How should I solve the issue? Or in General in case of using C codes in C++ projects what settings and MACRO (e.g. extern "C" in methods) should I follow
I don't know anything about the library you're trying to work with, because you did not tell us what it is. But I can make some guesses:
The code did not used to interface with Windows code at all;
By creating a Windows C++ application you have added Windows dependencies;
The Windows dependencies (well-known for poisoning the namespace with short names like BOOL) are conflicting with the library's code (which is doing the same thing with its BOOL macro, when defined, and its BOOL type alias, otherwise).
This isn't really to do with C vs C++ or anything like this, and there's no general fix you can make. You can either try to get rid of the Windows dependency (do you need that header for your task?) or you can patch your library not to touch BOOL (after making sure that Windows's BOOL is what you need it to be).
And use this as a good lesson not to pollute namespaces!

How to build the Poco C++ libraries

I'm trying to build the Poco C++ libraries manually on Android, iOS, and windows. After much effort I got them to build on Android, but I'm struggling a bit on Windows.
I've had to manually edit several files already to resolve undefined symbols -- specifically File & Path weren't #included properly by *_WIN32U.cpp versions.
I'm down to what APPEARS to be my last compiler issue for "Foundation". It's this line in Process_WIN32U.cpp:
envChars = getEnvironmentVariablesBuffer(env);
The compiler error generated is:
"getEnvironmentVariablesBuffer identifier not found"
The declaration of "getEnvironmentVariablesBuffer" is in Process.cpp but it's not a member of the root class, there are no EXTERN references anywhere, and no header file contains the function declaration.
So how the heck is "Process_WIN32U.cpp" supposed to be able to see that function?
Thanks!
So how the heck is "Process_WIN32U.cpp" supposed to be able to see that function?
ProcessWIN32U.cpp (i.e. ProcessImpl class) is able to see that function because ProcessWIN32U.cpp is included from Process.cpp and it was not designed or meant to be used standalone - it is excluded from build in POCO Visual Studio solutions.
In order to get ProcessWIN32U.cpp to be included by Process.cpp, one must manually /D_WIN32 which is not defined by Visual Studio (it defines WIN32).

(Hidden?) MS Visual Studio settings affecting C/C++ compilation

I have a C++ file that compiles fine in one project, but not in another. The file is the exact same C++ file in both projects.
Both projects are MFC dialog-based projects. They have slightly different stdafx.h files... but if I'm prepared to break the rest of the project, I can make them identical... and still get this compiler error. Equally, they have considerably different include paths, but if I break even more of the project and make the include paths identical, I still get the error. It goes without saying that I have made all my preprocessor directives identical... and I still get the error.
So, as far as I can tell, I'm down to compiler switches. I've made them identical (within reason - I haven't bothered to change the /Fp, /Fd or /Fo output files), but still it refuses to compile. Are there any "hidden" settings or anything else that might be affecting compilation?
[Note: the following is included mostly for historical reasons - it led to an unintentional over-emphasis when this question was originally posed, and so led to predictable comments and answers which didn't help resolve the intended "when is identical not identical?" question]
The error itself is error 2894 (templates cannot have 'C' linkage). I understand this error, but not how/why it is occurring. It occurs within a bunch of C header files pertaining to a C library. They are all neatly wrapped in extern "C" {...} declarations, with #ifdef __cplusplus correctly applied. But extern C {...} is not something I'm very familiar with, so... is there anything special about extern "C" {...} that might be a factor?
If a single C++ file is compiled under the same conditions, it leads to the same result. It doesn't matter if it is in a project with zero other files, or a hundred other files - the compiler compiles each file individually.
Therefore, if a single C++ file compiles with different results, then that is either because:
It is not really the same single C++ file, or
It is not really the same compilation conditions.
You can see exactly what the Microsoft Visual C++ compiler thinks your "single" C++ file truly is by specifying /showIncludes as an "advanced" compiler option. You might be surprised to see how different your "identical" C++ file is (and this was the case here).
Equally, you can see the explicit C++ compiler conditions listed under the Command Line summary that appears at the bottom of the list of C/C++ options in the project properties in Visual Studio.
wspapi.h includes some C++ template code outside of its internal extern "C" section. If you were to externally wrap the header in an extern "C" declaration, you would break it.
For example, you cannot do this:
extern "C"
{
#include <wspapi.h>
}
Similarly, if a preceding header or code has failed to terminate an extern "C" block so that all the content of the header is given C linkage, the same situation arises.
Put simply, wpsapi.h has been included within a C linkage block, it has nothing to do with "hidden options".

protocol buffers - generate NON-inline accessors

We're using protocol buffers (2.4.1) in a medium size embedded system w/ c# an c++ code. We use protobufs to isolate our managed and native layers w/ an easy to maintain serialization layer (For the curious, we would have just used Pinvoke, but we also have to run native code in a separate process on test/simulators).
Our system has a number of DLL's, and I have the generated native protobuf code in it's own DLL so that the other parts of the system can don't have to link in the generated code directly.
The problem i'm having is that all the generated accessors are inline, eg:
inline const ::MyProtoClassName::MyField& MyProtoClassName::myfield() const
{
return myfield_ != NULL ? *myfield_ : *default_instance_->myfield_;
}
use the generated API in size (the 'default_instance_' is dereferenced and accessed if this particular field not set). This means that I can't link (lnk2001) any clients using the accessors because there is not symbol default_instance_
I think the typical use case for ProtoBufs would be to have each component link in the generated protobuf code itself (after all, this is primarily a serialization layer for distributed systems), but
I'm wondering if there is a compile switch to change the inlining behavior that I missed. (Have all accessors defined in the CC file, not H)
Thanks!
Thanks #g-makulik! Looks like the answer was about 30 lines up in the ProtoC code, i just didn't see it :)
< see his answer below for the bulk of the solution > This should also help you, though.
As noted in some of Kenton's changelogs, adding this causes several warnings (C4251, c4275) relating to base classes that are not also DLLEXPORT'd
with the way ProtoBufs is implemented, and the protobuf classes being all templates, these warnings are benign. To cleanly ignore them (eg WITHOUT having to disable the warnings for all clients) I used this somewhat hacky approach:
-wrapper for the protobuf.h file that eveyone includes. (no one include the real generated H file)
#pragma once
#pragma warning(push)
#pragma warning(disable:4251)
#pragma warning(disable:4275)
// include the protobuf generated code; but exclude the warn c4251, c4275
// these relate to the dll exported
#include "yourProtoFile.h"
#pragma warning(pop)
and a wrapper C file (the real protobuf CC file is not in my project -> not built directly)
#include "MyProtoFile_WRAPPER.h"
#include "MyProtoFile.cc"
I think this link could answer your question: Protobuf with MSVC: how to export generated Message
Quote from Kenon Varga (Project leader of google protobuf):
If you invoke protoc like:
protoc --cpp_out=dllexport_decl=MY_EXPORT_MACRO:path/to/output/dir myproto.proto
then it will generate code with MY_EXPORT_MACRO in all the right places. However, this option is incomplete -- currently there is no way to force the generated .pb.h to #include a header which defines MY_EXPORT_MACRO. I'm open to patches to fix this. Or, you could use a hack to work around it, such as adding the #include via some sort of text processing after protoc finishes, or perhaps moving the .pb.h to .pb2.h and replacing the .pb.h file with one that first includes your header then includes the .pb2.h...
And additonally to cover the mentioned incompleteness (Quote from Aron Bierbaum):
We currently get around this limitation by forcing the the header to
be included using compiler command line flags:
Windows: /FIproject/Config.h
Linux: -include project/Config.h
NOTE:
Using the inline keyword shouldn't be relevant in this case (that an additional __declspec dllexport/__declspec dllimport attribute is put on the accessor method). Per definition it's up to the compiler to inline functions or not. Of course seeing a __declspec dllexport or __declspec dllimportattribute is contradictionary for inlining.

Show an error (in Visual studio), when someone tries to use STL in a current .cpp or .h file

In our company sometimes we write .cpp and .h files, which are used in projects for old WM (we use Embedded Visual C++ 3.0 or something for this) and in more modern code (VS 2010).
This Embedded Visual C++ does not support STL.
So if one of developers, who works in VS2010, changes a file, which is shared, and adds some function, which uses std::vector, for instance, on his side everything will be OK, but the build (which is quite long) will fail.
So to see this mistake sooner, I would like to add something like
#if defined(%%STL%%)
#error("!!!!")
#endif
in all files, which are compiled with old toolset. In this case the developer could see compile time error even in VS2010.
But I could not find what I can put instead %%STL%% there.
Any ideas? Or maybe someone knows a better way how I can do this?
Based on a comment to the question, you could go through each of the header files that aren't supported and see what symbols they define for their include guard. Then check for those symbols being defined.
E.G. The Microsoft C++ header <algorithm> defines _ALGORITHM_ so you can check for that:
#ifdef _ALGORITHM_
#error("<algorithm> included")
#endif
A bunch of these could be collected up and put into a single header file that you could include in each shared source file, at the end.
There is quite a nice solution (at least I do not see pitfalls)
%%STL%% should be _STD_BEGIN
this macro is used for "namespace std {" in VS stl implementation