Call a system C++ function from C [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
I have a C library, which I'm not really allowed to modify in substantial way, that heavily uses the random function, which is not available on my Visual Studio 2010 compiler (see another one of my questions)
So, I have to write my own random method. I tried to use a simple random() { srand(time(NULL)); return rand(); } but the library main conceptor doesn't like it (he's on Mac and I think he doesn't care much about my problems). He tells me to run srand() only once when the library is run, but since there might be multiple entry points in this lib, I don't know how to do it. If you have a solution to this problem, I'm all ears.
Update: I have found out that the "main" function is always run during the loading of the library (from what I understand), so I'll use this for the seeding. But I'm still interested in the solution to this particular question.
Update 2: well, calling srand() from main() produces always the same results, so that's not the answer after all :(
So I decided to follow another method of generating random numbers:
#include <Windows.h>
#include <wincrypt.h>
long int random() {
HCRYPTPROV prov;
if (CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0)) {
long int li = 0;
if (CryptGenRandom(prov, sizeof(li), (BYTE *)&li)) {
return li;
} else {
// random number not generated
return 0;
}
if (!CryptReleaseContext(prov, 0)) {
// context not released
return 0;
}
} else {
// context not created
return 0;
}
}
But then I get this kind of error:
error LNK2019: unresolved external symbol __imp__CryptReleaseContext#8
referenced in the function _random
The problem, if I understand correctly, is that I'm calling C++ functions from C, and C doesn't understand the name mangling happening during C++ compilation.
I have visited the classic answer to calling C++ from C, but I didn't see a way to call a system C++ function from a C method. Is there something I've missed?
Thanks!

Your problem seems to be something else: you have to link against Advapi32.lib to use the function CryptReleaseContext.
To do so:
Right click your project -> Properties -> Linker -> Input -> Additional Dependencies
Make sure, that Advapi32.lib is in the semicolon seperated list - otherwise add it there and rebuild your project. Then resolving the symbol __imp__CryptReleaseContext should be possible for your linker.

Related

unresolved external symbol "void __cdecl boost::tss_cleanup_implemented(void)"

I was very surprised when I tried to search this error as I got only 4 results, two of which seem to be in Chinese. I am getting this error when compiling my project and boost sources alltogether. I searched the boost library and found this:
namespace boost
{
/*
This file is a "null" implementation of tss cleanup; it's
purpose is to to eliminate link errors in cases
where it is known that tss cleanup is not needed.
*/
void tss_cleanup_implemented(void)
{
/*
This function's sole purpose is to cause a link error in cases where
automatic tss cleanup is not implemented by Boost.Threads as a
reminder that user code is responsible for calling the necessary
functions at the appropriate times (and for implementing an a
tss_cleanup_implemented() function to eliminate the linker's
missing symbol error).
If Boost.Threads later implements automatic tss cleanup in cases
where it currently doesn't (which is the plan), the duplicate
symbol error will warn the user that their custom solution is no
longer needed and can be removed.
*/
}
}
My question is what's tss cleanup, why is it needed and how do I implement it.
I don't know about TSS, but to fix this linker error, you need to define
BOOST_THREAD_WIN32
and
BOOST_THREAD_BUILD_LIB
so boost/thread/src/win32/tss_pe.cpp implements the missing function (empty).
I assume there are few results on the Internet for this question, because the build scenario is rare. Most people do not build boost within their own project, but build boost with b2.

c++ LNK2001 & LNK1120 compile errors [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I am debugging some C++ software, and want to modify an existing function slightly, so that it changes the value of a particular variable used elsewhere in the program.
The function is currently defined as so:
void DataStore::setEraseSelected(){
...
// Function code here
...
}
As it stands, the function works correctly with no problems whatsoever. But, I now want to modify the function, so that it will change the value of a variable used elsewhere in the program. To do this, I have tried passing the variable into the function as a parameter (I have also updated the header file to reflect the changes to the function), and then assigning a value to the variable inside the function:
void DataStore::setEraseSelected(toAMS::DataMessage statusMsg){
...
// Function code here
...
statusMsg.CODE_ERASE = Types::Activated;
...
}
As mentioned, I have added the declaration to the header file, so that it now has the declaration for the function with the parameter, as well as the one for the function without the parameter:
void DataStore::setEraseSelected(toAMS::DataMessage statusMsg);
But when I try and build the code (using Visual Studio 2010), I get the following two compile errors:
error LNK2001: unresolved external symbol "public void_thiscall DataStore::setEraseSelected(void)" (? setEraseSelected#DataStore::QAEXXZ)
error LNK1120: 1 unresolved externals
The first error highlights the project .obj file, which I have tried deleting and building again, but get the same error, and second one highlights the project .exe file, which I have also tried deleting and building again, but get the same error.
Anyone have any ideas why? I've had a look on SO for questions regarding these errors, but none of them seem to clearly explain why I might be getting them. They all seem to suggest that the compiler is possibly looking in the wrong place, but if I undo my changes, then the code compiles with no problems, and I haven't told the compiler to look anywhere else when building the code with my changes...
void DataStore::setEraseSelected(int );
Pass that variable

LNK2019, LPCTSTR, and C++ syntax in general

Allow me to preface this question with 2 comments:
1) I'm a C# developer, so I don't have much practice dealing with linker errors in C++ and some standard C++ syntax is a bit unfamiliar to me. I suspect this will be an easy question to the C++ gurus out there.
2) I'm not sure how to ask this question in a way that will be relevant to the masses but I'm open to suggestions/corrections from the community. The problem with lnk2019 errors is that it seems pretty individualized as to what the problem actually is. MSDN has an article that deals with the error generally and Stack Overflow already has a slew of questions with that tag and yet I still can't seem to solve my problem.
On to the details...
I was given an old (VS2005) C++ solution with 42 projects and was asked to try and get it to build. After doing quite a bit of twiddling, I've gotten it down to just 3 projects that won't build. I'd like to focus on just one of them because I think if we can figure that one out, I can do the same things to the other 2 projects to fix them.
Let's start with the error. As you can see, the project in question is named "HttpWire".
Deleting intermediate and output files for project 'Http Wire',
configuration 'Release|x64' Compiling... HttpWire.cpp
Compiling resources... Linking... Creating library
Release\AMD64\HttpWire.lib and object Release\AMD64\HttpWire.exp
HttpWire.obj : error LNK2019: unresolved external symbol "public:
__cdecl THttpWire::THttpWire(char const *)" (??0THttpWire##QEAA#PEBD#Z) referenced in function
CreateConnectionWire Release\AMD64\HttpWire.dll : fatal error LNK1120:
1 unresolved externals
Looks like the linker is upset because the function "CreateConnectionWire" is calling "THttpWire" but for some reason the linker is unable to find it. There is only 1 .cpp file in the project (HttpWire.cpp) and here it is:
#include "THttpWire.h"
BOOL WINAPI DllMain(HINSTANCE hDllInst, DWORD reason, LPVOID reserved)
{
return TRUE;
}
__declspec(dllexport) TConnectionWire *CreateConnectionWire(LPCTSTR connectionString)
{
return new THttpWire(connectionString);
}
__declspec(dllexport) void DeleteConnectionWire(TConnectionWire *connectionWire)
{
delete connectionWire;
}
The #include file, "THttpWire.h" lives in another project called "AirTime Core". It includes several other things and then has the following:
class THttpWire : public TConnectionWire
{
public:
THttpWire(LPCTSTR connectionString);
virtual ~THttpWire();
... (lots of other stuff) ...
}
And then, finally, we have THttpWire.cpp:
#include "THttpWire.h"
...
THttpWire::THttpWire(LPCTSTR connectionString) :
TConnectionWire(connectionString),
hWinHttp(NULL), hSession(NULL), hRequest(NULL),
opTimedOut(FALSE), asyncError(0),
headers(NULL), headersOffset(0), headersLength(0),
availData(0)
{
requestSent = new TSyncEvent(TRUE);
updateToString();
}
This syntax is a bit weird to me... what are we doing here? I mean, I realize this is a constructor, and since THttpWIre appears to inherit from TConnectionWire (according to the .h), then the ":TConnectionWire(connectionString)" makes sense (I'm assuming this is like C# appending ": base()" to constructors of objects that inherit from other objects), but then what is all the other stuff between that and the opening brace (note that TConnectionWire does not appear to inherit from anything else)?
SO...
After doing some searching on MSDN and SO, I've learned the following (please correct me if I'm wrong)
CreateConnectionWire is prefaced by __declspec(dllexport) which simply makes it available to other projects consuming this .dll (as discussed here)
LPCTSTR is a const char* (see MSDN). Note that my projects are set with "Treat wchar_t as Built-in Type: No (/Zc:wchar_t-)" in the property pages. (see the bottom of this article and also this article)
Right now, my primary suspicion is with LPCTSTR. Perhaps it is not defined the same in both projects, which would yield different method signatures... but I don't know how to check for this or fix it if that is the case. Or, perhaps the "/Zc:wchar_t-" thing is affecting it adversely?My next suspicion is that there is something in the string of methods listed in the constructor (with the syntax that I don't understand) that is causing some sort of problem and making the "THttpWire" constructor not available, generally.What do you think? I'd be happy to share any other bits that you think would be useful.
Other information that may or may not be helpful (I'll let you decide)
When I first started with this project, there were several .lib and .h files missing and I've had to go around trying to find them (examples were opends60.lib, mssoap30.lib, WinLUA.h, etc.). It is quite possible I don't have the same version the solution was originally built against.
The projects were all built with "_WIN32_WINNT=0x0400" defined, which appears to mean it was meant to be built against the Windows 2000 SDK (see MSDN). I found something that I thought was the Win 2000 SDK (the oldest one on here, but when I link to that, I get many more errors. Instead, I'm linking to the SDK version 6.1. HOWEVER, this causes WinHttp not to compile because "SOCKADDR_STORAGE" isn't defined for anything "_WIN32_WINNT<0x0501" (windows XP). THUS, I've redefined "_WIN32_WINNT=0x0501" for all of the projects that appear to be related to HttpWire. It is possible I missed one or two.
There is only 1 .cpp file in the project (HttpWire.cpp)
Well, that's a problem because clearly you need more than 1. You also need THttpWire.cpp since it contains the constructor code. The one that the linker cannot find.
Keep the C++ build model in mind, it is very different from C#. Source code files are separately compiled. And then the linker glues all the bits of code together to make the program. Those bits may come from an .obj file created from a .cpp file. Or they could come from a .lib file, a "container" of bits of code.
Which is the likely explanation since you mentioned an "AirTime Core" project. Project + Properties, Linker, Input, Additional Dependencies setting. You need to add the output of the "AirTime Core" project, whatever it is named.

Linking Error in C++ development in Visual Studios 2008

I am doing c++ porting/development in visual studios 2008.
I am getting the following issues.
1) Variable sized array not allowed.
2) Linking error for any of the undefined functions of the class even if they are not referenced.(error LNK2001: unresolved external symbol "public: virtual void __thiscall ...)
I think these are related to the version of the c++ language VS2008 support.
I am trying a compile and link large c++ codebase. I cannot substitute variable sized array with new/alloc. Please give me solution so that I can use the existing code.
Can anyone please help me sort this out?
But the following code works fine in the same VS2008
class Hello
{
public:
int a;
public:
virtual void add();
};
class bye : public Hello
{
public:
int y;
public:
void add();
};
int main()
{
std::cout << "got";
}
Where am I going wrong?
Virtual functions are considered "used" if you have a single instance of a class created anywhere. Your link error indicate that certain virtual functions are not implemented. As the error list all of them by name it must be a trivial task to locate them, end figure out if you failed to include some code, compiled with different options, or they were indeed unimplemented in the source place -- in which case you can just add blank implementations calling terminate.
For the VLA problem: that extemsion is not present in VS2008, period. Even if you wait some years and VS201y will implement the new VLA-like thing in C++14, it will not go back to your chosen compiler. (kinda weird if you ask me to chose a 5-year old bug-ridden beast that has dropped of support long ago, instead of the current...)
But std::vector does almost the same as VLA, and if you find difference you can write a beter wrapper or a few adapter functions. The place of memory allocation is not something you can discover legally in the program anyway. In case you'd hit some performance bottleneck, that is doubtful from such a change, you can rearrange a small portion of code.
How about use std::vector to replace the arrays?

Multiple definitions of "Main"

In the journey to learning C++ im learning through the C++ Manual thats on the actual website. Im using DevC++ and have hit a problem, not knowing whether its the compilers error or not.
I was going through this code bit by bit typing it in myself, as I feel its more productive, and adding my own stuff that ive learnt to the examples, then I get to initialising variables. This is the code that is in the C++ manual
#include <iostream>
using namespace std;
int main ()
{
int a=5; // initial value = 5
int b(2); // initial value = 2
int result; // initial value undetermined
a = a + 3;
result = a - b;
cout << result;
return 0;
}
This is popping up a compiler error saying " Multiple definitions of "Main""
Now This is on the actual C++ page so im guessing its a compiler error.
Could someone please point me in the right direction as to why this is happening and what is the cause for this error.
Multiple definitions of "main" suggests that you have another definition of main. Perhaps in another .c or .cpp file in your project. You can only have one function with the same name and signature (parameter types). Also, main is very special so you can only have one main function that can be used as the entry point (has either no parameters, one int, or an int and a char**) in your project.
P.S. Technically this is a linker error. It's a subtle difference, but basically it's complaining that the linker can't determine which function should be the entry point, because there's more than one definition with the same name.
Found I had two file references in my tasks.json file that were causing this error and which took me a long time to figure out. Hope this helps someone else..... See "HERE*****" below:
"-I/usr/include/glib-2.0",
"-I/usr/lib/x86_64-linux-gnu/glib-2.0/include",
//"${file}", //HERE**********************
"-lgtk-3",
"-lgdk-3",
"-lpangocairo-1.0",
"-lpango-1.0",
"-lharfbuzz",
"-latk-1.0",
"-lcairo-gobject",
"-lcairo",
"-lgdk_pixbuf-2.0",
"-lgio-2.0",
"-lgobject-2.0",
"-lglib-2.0",
"-o",
"${fileDirname}/${fileBasenameNoExtension}" //HERE*************
],
When I practiced CMake, I encountered the same problem. Finally, I found that the source code path set in the cmakelist project was incorrect. As a result, the compiled files included many duplicate files generated during CMake execution. As a result, compilation errors occurred