I'm trying to send an HTTPS request in c++ using Cpp-httplib but I'm getting various errors and warnings building their example:
#include "stdafx.h"
#include <httplib.h>
#include <Windows.h>
#include <iostream>
#define CA_CERT_FILE "./ca-bundle.crt"
#define CPPHTTPLIB_OPENSSL_SUPPORT 1
using namespace std;
int main()
{
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
httplib::SSLClient cli("localhost", 8000);
//httplib::SSLClient cli("google.com");
// httplib::SSLClient cli("www.youtube.com");
cli.set_ca_cert_path(CA_CERT_FILE);
cli.enable_server_certificate_verification(true);
#else
httplib::Client cli("localhost", 8000);
#endif
char* x = { "hello world" };
httplib::Params params{
{ "key", x }
};
auto res = cli.Post("/postReq/", params);
if (res) {
cout << res->status << endl;
cout << res->get_header_value("Content-Type") << endl;
cout << res->body << endl;
}
else {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto result = cli.get_openssl_verify_result();
if (result) {
cout << "error";
cout << "verify error: " << X509_verify_cert_error_string(result) << endl;
}
#endif
}
system("pause");
return 0;
}
This is the build output:
Call to 'std::basic_string::copy' with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
error C2039: 'SSLClient': is not a member of 'httplib'
error C2065: 'SSLClient': undeclared identifier
error C3861: 'X509_verify_cert_error_string': identifier not found
I am new to this issue so I will provide some other information that might help:
I have installed OpenSSL (x64 1.1.1g version).
I have linked libssl.lib and libcrypto.lib in my project.
I don't think that this is related to OpenSSL's configuration because I have already created a self-certificate.I think the issue is with cpp-httplib but I dont know how to fix it.
Try this. The definition must be before including the library.
#include "stdafx.h"
>>> #define CPPHTTPLIB_OPENSSL_SUPPORT
#include <httplib.h>
#include <Windows.h>
#include <iostream>
#define CA_CERT_FILE "./ca-bundle.crt"
using namespace std;
int main()
{
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
httplib::SSLClient cli("localhost", 8000);
//httplib::SSLClient cli("google.com");
// httplib::SSLClient cli("www.youtube.com");
cli.set_ca_cert_path(CA_CERT_FILE);
cli.enable_server_certificate_verification(true);
#else
httplib::Client cli("localhost", 8000);
#endif
char* x = { "hello world" };
httplib::Params params{
{ "key", x }
};
auto res = cli.Post("/postReq/", params);
if (res) {
cout << res->status << endl;
cout << res->get_header_value("Content-Type") << endl;
cout << res->body << endl;
}
else {
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto result = cli.get_openssl_verify_result();
if (result) {
cout << "error";
cout << "verify error: " << X509_verify_cert_error_string(result) << endl;
}
#endif
}
system("pause");
return 0;
}
Related
I'm compiling some C++ with emscripten and I'm having a problem to use some features from gsl such as "Expects". The emcc can't find "gsl/gsl".
How can I compile it with gsl?
Here is the header file:
#ifndef ROBOT_CPP_PWMTEST_H
#define ROBOT_CPP_PWMTEST_H
#include <iostream>
#include <gsl/gsl>
class PwmTest {
public:
int duty_cycle_pwm_a;
int duty_cycle_pwm_b;
explicit PwmTest();
~PwmTest();
int setPwmA(int duty_cycle);
int getPwmA();
};
#endif //ROBOT_CPP_PWMTEST_H
Here is the source file:
#include "PwmTest.h"
PwmTest::PwmTest()
{
duty_cycle_pwm_a = 0;
duty_cycle_pwm_b = 0;
std::cout << "PWM instance Created" << std::endl;
}
PwmTest::~PwmTest()
{
std::cout << "PWM instance Destroyed" << std::endl;
}
int PwmTest::setPwmA(int duty_cycle)
{
Expects(-1 < duty_cycle && duty_cycle <= 100);
duty_cycle_pwm_a = duty_cycle;
std::cout << "PWM A is set to " << duty_cycle_pwm_a << std::endl;
return 0;
}
int PwmTest::getPwmA()
{
std::cout << "PWM A value is: " << duty_cycle_pwm_a << std::endl;
return duty_cycle_pwm_a;
}
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#include <emscripten/bind.h>
EMSCRIPTEN_BINDINGS(pwm_class_emscripten) {
emscripten::class_<PwmTest>("PwmTest")
.constructor<>()
.function("setPwmA", &PwmTest::setPwmA)
.function("getPwmA", &PwmTest::getPwmA)
.property("duty_cycle_pwm_a", &PwmTest::duty_cycle_pwm_a)
;
}
#endif
It works if I take the gsl off of it.
So I'm fairly new to C++ and I've only started to code into it a few weeks or so. I've been facing a problem that I could not manage to fix. Every time I learned a new programming language, I give myself the challenge to make a little program (not too complex) which groups everything I've learned about that language (functions, classes, arrays, pointers and so on) so I can get a good understand of how actually coding in that language is.
So I decided to make my first C++ program called Chek to check the current MBPS (connection speed) every hour, minutes, or second that the user can input. Like all of my programs, I use a structure that I always use that I discovered while coding in Java (Since I know Java fluidly). Which looks like this:
I've also added a comment of where my issue is in the whole in Lib/Arguments.cpp.
Let's say I was to code Chek in Java. I would do my structure like:
Chek or Main class
|- Core
|- Core (The class that handles initiating each core's libraries)
|- Arguments (For parsing, checking and understand arguments)
|- Broadcast (To print to screen and so on)
|- Network (For network interaction)
|- Logs (To save to file logs)
Then the rest ...
Each Core's lib is handled by the Core, like... To call the Broadcast methods, I would do:
Main().getCore().getBroadcast().BroadcastMsg("Hello!");
So I can access all libraries, methods, and variables without creating deadlocks or any infinite importing loops.
My problem is I'm trying to do this in C++ but it's not working! I've tried a lot of stuff, changing pointers to Object and so on but it doesn't work so I need help!
Here's my code (I'm also using Visual Studio):
Chek.cpp:
#include "pch.h"
#include "Main.h"
#include "Core.h"
#include <iostream>
int main(int argc, char *argv[])
{
Core* Ptr = new Core;
Main OBJ; Main* Ptr2; Ptr2 = &OBJ;
std::cout << "Generated PTR's!" << std::endl;
std::cout << "Core PTR -> " << Ptr << std::endl;
std::cout << "Main PTR -> " << Ptr2 << std::endl << std::endl;
Ptr2->SetCrPtr(Ptr);
Ptr2->loadChek(argv);
}
Main/Main.h:
#pragma once
#ifndef __MAIN_H
#define __MAIN_H
class Core;
class Main
{
public:
Main();
private:
Core* CrPtr;
public:
void loadChek(char *arguments[]);
void SetCrPtr(Core* Ptr);
Core* getCrPtr();
};
#endif
Main/Main.cpp:
#include "pch.h"
#include "Main.h"
#include "Core.h"
#include "Arguments.h"
#include "Broadcast.h"
#include <iostream>
using namespace std;
Main::Main() : CrPtr() {};
void Main::SetCrPtr(Core* Ptr)
{
std::cout << "[Main] Setting CrPtr to " << Ptr << std::endl;
this->CrPtr = Ptr;
}
Core* Main::getCrPtr()
{
return this->CrPtr;
}
void Main::loadChek(char *arguments[])
{
char *allArguments[sizeof(arguments)];
this->CrPtr->SetMnPtr(this);
this->CrPtr->setArguments();
this->CrPtr->setBroadcast();
this->CrPtr->getBroadcast()->Log(1, "Loading arguments ...\n");
this->CrPtr->getArguments()->parseArguments(arguments, allArguments);
}
Core/Core.h:
#pragma once
#ifndef __CLASS_H
#define __CLASS_H
#include "Arguments.h"
#include "Broadcast.h"
class Main;
class Core
{
public:
Core();
private:
Main* MnPtr;
Arguments* ArgPtr;
Broadcast* BrdPtr;
public:
Arguments* getArguments();
void setArguments();
Broadcast* getBroadcast();
void setBroadcast();
void SetMnPtr(Main* Ptr);
};
#endif
Core/Core.cpp:
#include "pch.h"
#include "Core.h"
#include "Main.h"
Core::Core() : MnPtr() {}
void Core::SetMnPtr(Main* Ptr)
{
std::cout << "[Core] Setting MnPtr to " << Ptr << std::endl;
this->MnPtr = Ptr;
}
void Core::setArguments()
{
this->ArgPtr = new Arguments;
std::cout << "[Core] Setting Argument's MnPtr to " << this->MnPtr << std::endl;
this->ArgPtr->SetMnPtr(this->MnPtr);
}
void Core::setBroadcast()
{
this->BrdPtr = new Broadcast;
std::cout << "[Core] Setting Broadcast's MnPtr to " << this->MnPtr << std::endl;
this->BrdPtr->SetMnPtr(this->MnPtr);
}
Arguments* Core::getArguments()
{
return ArgPtr;
}
Broadcast* Core::getBroadcast()
{
return BrdPtr;
}
Lib/Arguments.h:
#pragma once
class Main;
class Arguments
{
public:
Arguments();
private:
Main* MnPtr;
public:
void parseArguments(char *arguments[], char *argumentsElements[]);
void SetMnPtr(Main* Ptr);
Main* GetMnPtr();
};
Lib/Arguments.cpp:
#include "pch.h"
#include "Arguments.h"
#include <iostream>
Arguments::Arguments() : MnPtr() {}
void Arguments::SetMnPtr(Main* Ptr)
{
std::cout << "[Arguments] Setting MnPtr to " << Ptr << std::endl;
this->MnPtr = Ptr;
}
Main* Arguments::GetMnPtr()
{
return this->MnPtr;
}
void Arguments::parseArguments(char *arguments[], char *argumentsElements[])
{
try {
if (sizeof(arguments) == 1 || sizeof(arguments) > 4) throw 1;
}
catch (int errorCode) {
if (errorCode == 1) std::cout << "Wrong usage!\n\nUsage: chek.exe <timeout-in-miliseconds> <log-file-path>\nExample: chek.exe 10000 saturday_log_file.txt\n";
}
std::cout << "Size -> " << sizeof(arguments) << std::endl;
for(int i=0; i<sizeof(arguments); i++)
{
// The error is produced here, for some reason after MnPtr,
// nothing is recognised. Like getCrPtr()... has never been declared?
this->MnPtr->getCrPtr()->getBroadcast()->(1, "Works!");
}
}
Lib/Broadcast.h:
#pragma once
#include <iostream>
#include "Main.h"
class Broadcast
{
public:
Broadcast();
private:
Main* MnPtr;
public:
void Log(unsigned int statusLevel, std::string message);
void SetMnPtr(Main* Ptr);
};
Lib/Broadcast.cpp:
#include "pch.h"
#include "Broadcast.h"
#include <iostream>
#include <string>
using namespace std;
Broadcast::Broadcast() : MnPtr() {}
void Broadcast::SetMnPtr(Main* Ptr)
{
std::cout << "[Broadcast] Setting MnPtr to " << Ptr << std::endl;
this->MnPtr = Ptr;
}
void Broadcast::Log(unsigned int statusLevel, string message)
{
switch (statusLevel) {
case 1:
cout << "[.] " << message;
break;
case 2:
cout << "[+] " << message;
break;
case 3:
cout << "[!] " << message;
break;
case 4:
cout << "[X] " << message;
break;
}
}
Errors:
I get 3 errors.
Visual Studio Error (When you hover it):
Arguments *const this
Pointers to incomplete class is not allowed.
From the error box (Visual Studio):
Error C2027 use of undefined type 'Main' Chek2 c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.cpp 30
Error (active) E0393 pointer to incomplete class type is not allowed Chek2 C:\Users\xxx\Documents\Programming\C++\VS Workspace\Chek2\Arguments.cpp 30
Compiler Errors:
1>c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.cpp(30): error C2027: use of undefined type 'Main'
1>c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.h(3): note: see declaration of 'Main'
If anyone could help me with this. I would highly appreciate it! I hope it's not too hard of a problem- fairly new to C++ so I don't know exactly what this is compared to Java.
Thanks to #drescherjm for answering in comments. I just needed to add:
#include "Main.h"
#include "Core.h"
Inside Arguments.cpp's includes!
This is about C ++ library boost.
The managed_mapped_file :: shrink_to_fit function works differently on Linux and Windows.
On Linux, this function succeeds even if the target instance exists.
However, on Windows, this function will fail if the target instance exists.
Is this correct behavior?
It seems correct to do the same behavior, is this a bug?
I put the sample code below.
Compilation environment
boost:version.1.65.1
Windows
VisualStudio2017
WSL(Ubuntu16.04)
Linux
UbuntuServer17.10,
Clang++5.0,
g++7.2.0
Compile with
clang++-5.0 -std=c++1z ./test.cpp -o test -lpthread
#define BOOST_DATE_TIME_NO_LIB
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <vector>
#include <iostream>
namespace bip = boost::interprocess;
using intAlloc = bip::allocator<int, bip::managed_mapped_file::segment_manager>;
using intVec = std::vector<int, intAlloc>;
int main() {
bip::managed_mapped_file *p_file_vec;
intVec *vecObj;
std::string fileName = "tmp.dat";
size_t fileSize = 1024 * 1024 * 1;
bip::file_mapping::remove(fileName.c_str());
p_file_vec = new bip::managed_mapped_file(bip::create_only, fileName.c_str(), fileSize);
vecObj = p_file_vec->construct<intVec>("myVecName")(p_file_vec->get_allocator<int>());
for (size_t i = 0; i < 10; i++)
{
vecObj->push_back(1 + 100);
}
p_file_vec->flush();
try
{ //Fail when execute on Windows(WSL),but Success on Linux(Ubuntu17.10).
std::cout << "try to shrink:pointer has existed yet!" << std::endl;
bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
std::cout << "success to shrink!" << std::endl;
}
catch (const boost::interprocess::interprocess_exception &ex)
{
std::cerr << "fail to shrink!" << std::endl;
std::cerr << ex.what() << std::endl;;
}
std::cout <<"please pless enter key."<< std::endl;
std::cin.get();
try
{ //Success when execute on Windows(WSL) and Linux(Ubuntu17.10).
delete p_file_vec;
std::cout << "try to shrink:pointer has deleted!" << std::endl;
bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
std::cout << "success to shrink!" << std::endl;
}
catch (const std::exception& ex)
{
std::cerr << "fail to shrink!" << std::endl;
std::cerr << ex.what() << std::endl;;
}
std::cout << "please pless enter key." << std::endl;
std::cin.get();
}
Don't use new and delete in C++ (rule of thumb).
Apart from that
delete p_file_vec;
does NOT delete anything physical. It effectively disconnects from the mapped file. This is also why shrink_to_fit works: the documentation explicitly says:
If the application can find a moment where no process is attached it can grow or shrink to fit the managed segment.
And here
So, in short: the behaviour is correct on both platforms. It's just UNDEFINED what happens in your case when you shrink while the mapped file is in use (on Ubuntu).
Fixed Code:
Live On Coliru
#include <boost/interprocess/managed_mapped_file.hpp>
#include <iostream>
#include <vector>
namespace bip = boost::interprocess;
using intAlloc = bip::allocator<int, bip::managed_mapped_file::segment_manager>;
using intVec = std::vector<int, intAlloc>;
int main() {
std::string const fileName = "tmp.dat";
bip::file_mapping::remove(fileName.c_str());
{
bip::managed_mapped_file file_vec(bip::create_only, fileName.c_str(), 1l << 20);
auto *vecObj = file_vec.construct<intVec>("myVecName")(file_vec.get_allocator<int>());
for (size_t i = 0; i < 10; i++) {
vecObj->push_back(1 + 100);
}
}
try { // Success when execute on Windows(WSL) and Linux(Ubuntu17.10).
std::cout << "try to shrink:pointer has deleted!" << std::endl;
bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
std::cout << "success to shrink!" << std::endl;
} catch (const std::exception &ex) {
std::cerr << "fail to shrink!" << std::endl;
std::cerr << ex.what() << std::endl;
;
}
}
I am trying to use clang+llvm 3.6 to JIT compile several C functions (each can eventually be very large).
Unfortunately I the function pointer that LLVM provides makes the program SEGFAULT.
So far I have following code:
#include <iostream>
#include <clang/CodeGen/CodeGenAction.h>
#include <clang/Basic/DiagnosticOptions.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Basic/SourceManager.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/CompilerInvocation.h>
#include <clang/Frontend/FrontendDiagnostic.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Frontend/Utils.h>
#include <clang/Parse/ParseAST.h>
#include <clang/Lex/Preprocessor.h>
#include <llvm/Analysis/Passes.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/IR/Verifier.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/Linker/Linker.h>
int main(int argc, char *argv[]) {
using namespace llvm;
using namespace clang;
static const char* clangArgv [] = {"program", "-x", "c", "string-input"};
static const int clangArgc = sizeof (clangArgv) / sizeof (clangArgv[0]);
// C functions to be compiled (they could eventually be extremely large)
std::map<std::string, std::string> func2Source;
func2Source["getOne"] = "int getOne() {return 1;}";
func2Source["getTwo"] = "int getTwo() {return 2;}";
llvm::InitializeAllTargets();
llvm::InitializeAllAsmPrinters();
std::unique_ptr<llvm::Linker> linker;
std::unique_ptr<llvm::LLVMContext> context(new llvm::LLVMContext());
std::unique_ptr<llvm::Module> module;
/**
* add each C function to the same module
*/
for (const auto& p : func2Source) {
const std::string& source = p.second;
IntrusiveRefCntPtr<DiagnosticOptions> diagOpts = new DiagnosticOptions();
TextDiagnosticPrinter *diagClient = new TextDiagnosticPrinter(llvm::errs(), &*diagOpts); // will be owned by diags
IntrusiveRefCntPtr<DiagnosticIDs> diagID(new DiagnosticIDs());
IntrusiveRefCntPtr<DiagnosticsEngine> diags(new DiagnosticsEngine(diagID, &*diagOpts, diagClient));
ArrayRef<const char *> args(clangArgv + 1, // skip program name
clangArgc - 1);
std::unique_ptr<CompilerInvocation> invocation(createInvocationFromCommandLine(args, diags));
if (invocation.get() == nullptr) {
std::cerr << "Failed to create compiler invocation" << std::endl;
exit(1);
}
CompilerInvocation::setLangDefaults(*invocation->getLangOpts(), IK_C,
LangStandard::lang_unspecified);
invocation->getFrontendOpts().DisableFree = false; // make sure we free memory (by default it does not)
// Create a compiler instance to handle the actual work.
CompilerInstance compiler;
compiler.setInvocation(invocation.release());
// Create the compilers actual diagnostics engine.
compiler.createDiagnostics(); //compiler.createDiagnostics(argc, const_cast<char**> (argv));
if (!compiler.hasDiagnostics()) {
std::cerr << "No diagnostics" << std::endl;
exit(1);
}
// Create memory buffer with source text
std::unique_ptr<llvm::MemoryBuffer> buffer = llvm::MemoryBuffer::getMemBufferCopy(source, "SIMPLE_BUFFER");
if (buffer.get() == nullptr) {
std::cerr << "Failed to create memory buffer" << std::endl;
exit(1);
}
// Remap auxiliary name "string-input" to memory buffer
PreprocessorOptions& po = compiler.getInvocation().getPreprocessorOpts();
po.addRemappedFile("string-input", buffer.release());
// Create and execute the frontend to generate an LLVM bitcode module.
clang::EmitLLVMOnlyAction action(context.get());
if (!compiler.ExecuteAction(action)) {
std::cerr << "Failed to emit LLVM bitcode" << std::endl;
exit(1);
}
std::unique_ptr<llvm::Module> module1 = action.takeModule();
if (module1.get() == nullptr) {
std::cerr << "No module" << std::endl;
exit(1);
}
if (linker.get() == nullptr) {
module.reset(module1.release());
linker.reset(new llvm::Linker(module.get()));
} else {
if (linker->linkInModule(module1.release())) {
std::cerr << "LLVM failed to link module" << std::endl;
exit(1);
}
}
}
llvm::InitializeNativeTarget();
llvm::Module* m = module.get();
std::string errStr;
std::unique_ptr<llvm::ExecutionEngine> executionEngine(EngineBuilder(std::move(module))
.setErrorStr(&errStr)
.setEngineKind(EngineKind::JIT)
.setMCJITMemoryManager(std::unique_ptr<SectionMemoryManager>(new SectionMemoryManager()))
.setVerifyModules(true)
.create());
if (!executionEngine.get()) {
std::cerr << "Could not create ExecutionEngine: " + errStr << std::endl;
exit(1);
}
executionEngine->finalizeObject();
/**
* Lets try to use each function
*/
for (const auto& p : func2Source) {
const std::string& funcName = p.first;
llvm::Function* func = m->getFunction(funcName);
if (func == nullptr) {
std::cerr << "Unable to find function '" << funcName << "' in LLVM module" << std::endl;
exit(1);
}
// Validate the generated code, checking for consistency.
llvm::raw_os_ostream os(std::cerr);
bool failed = llvm::verifyFunction(*func, &os);
if (failed) {
std::cerr << "Failed to verify function '" << funcName << "' in LLVM module" << std::endl;
exit(1);
}
#if 1
func->dump(); // Dump the function for exposition purposes.
// JIT the function, returning a function pointer.
void *fPtr = executionEngine->getPointerToFunction(func); ///// BAD function pointer!!!!
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
int (*funcPtr)();
*(int **) (&funcPtr) = *(int **) fPtr;
int v = (*funcPtr)();
std::cout << "return: " << v << std::endl;
#else // THIS DOES NOT WORK EITHER:
// JIT the function, returning a function pointer.
uint64_t fPtr = executionEngine->getFunctionAddress(funcName); ///// BAD function pointer!!!!
if (fPtr == 0) {
std::cerr << "Unable to find function '" << funcName << "' in LLVM module" << std::endl;
exit(1);
}
int (*funcPtr)();
*(int **) (&funcPtr) = *(int **) fPtr;
int v = (*funcPtr)();
std::cout << "return: " << v << std::endl;
#endif
}
}
Can anyone help me pin-point the problem?
(I'm running this in linux-ubuntu 15.04)
This assignment is incredibly messed up:
*(int **) (&funcPtr) = *(int **) fPtr;
Not only does it violate strict-aliasing to write an int* and then use it as a function pointer on the next line, but a data pointer is often not large enough to hold an entire code pointer.
The safe approach is either
memcpy(funcPtr, fPtr, sizeof funcPtr);
or
funcPtr = reinterpret_cast<decltype(funcPtr)>(fPtr);
I'm doing my first VC++ project and am using the following code. The project has the following files.
Project1.cpp
#include "stdafx.h"
#include <iostream>
#include "PopulateDB.h"
using namespace std;
int main (void)
{
PopulateDB x;
x.calcUpload();
return 0;
}
PopulateDB.h
#pragma once
#include "mysql_connection.h"
#include <cppconn/driver.h>
class PopulateDB
{
public:
int calcUpload(void);
PopulateDB(void);
~PopulateDB(void);
private:
int updateMA(sql::Connection &);
};
PopulateDB.cpp
#include "StdAfx.h"
#include "PopulateDB.h"
#include <iostream>
#include "mysql_connection.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include "Technical.h"
using namespace std;
int updateMA(sql::Connection& con)
{
sql::Statement *stmt;
sql::ResultSet *res;
int i;
stmt = con.createStatement();
res = stmt->executeQuery("SELECT * from PriceAMS");
while(res->next())
{
cout << "Symbol " << i << " = " << res->getBlob("Symbol") << endl;
i++;
}
delete stmt;
}
int calcUpload(void)
{
cout << "Running Connection..." << endl;
try
{
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "nishantd", "mySQLDB%passWord2013"); //we can initialize the user/pass in constructor
/* Connect to the MySQL test database */
con->setSchema("testMMDB");
cout << "Looks like it connected..." << endl;
updateMA(*con);
delete con;
}
catch (sql::SQLException &e)
{
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
return 0;
}
PopulateDB::PopulateDB(void)
{
}
PopulateDB::~PopulateDB(void)
{
}
Technical.h
#pragma once
#include <vector>
class Technical
{
public:
float StandardMovingAverage(std::vector<float> values);
float StdDev(std::vector<float> values);
float Variance(std::vector<float> values);
int RSI(std::vector<float> values);
Technical(void);
~Technical(void);
};
Technical.cpp
#include "StdAfx.h"
#include "Technical.h"
#include <cmath>
#include <vector>
using namespace std;
float Technical::StandardMovingAverage(vector <float> values)
{
int sum=0;
for(int i=0; i < values.size(); i++)
sum+=values[i];
return sum/values.size();
}
float Technical::StdDev(vector <float> values)
{
float E=0;
float ave = StandardMovingAverage(values); //this function just calculates the mean values
for(int i=0; i < values.size(); i++)
E+=(values[i]- ave)*(values[i]- ave);
return sqrt(1/values.size()*E);
}
float Technical::Variance(vector <float> values)
{
return StdDev(values)*StdDev(values);
}
Technical::Technical(void)
{
}
Technical::~Technical(void)
{
}
I am getting the following error in VC++ 2010. There are warnings which I am currently ignoring
1>Project1.obj : error LNK2001: unresolved external symbol "public: int __thiscall PopulateDB::calcUpload(void)" (?calcUpload#PopulateDB##QAEHXZ)
1>D:\Project\CPP\Project1\Release\Project1.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I am trying to resolve this and get my code to work. Its even more frustrating because I suspect I am missing something very basic since I am new to VC++ and the code anyway doesn't do much in its current shape.
Really appreciate all help
Thanks,
Nick
You are calling a function named PopulateDB::calcUpload - a member function of class PopulateDB. But you've never actually implemented that function. You did implement a different, standalone, non-member function named ::calcUpload, but you are not calling it.
In your implementation file, make it
int PopulateDB::calcUpload() {...}