LLVM creating executable code from C/C++ builder - c++

I have get an example llvm code from here. This code has some problems that I fixed them too. At this point, all it does is to dump the translated IR code. What I am after is to create an executable from my C++ code without calling llvm-as/llc/clang in my bash. How can I achieve that?
I do not want to create any IR or bytecode intermediate file at all too.
#include <llvm/ADT/ArrayRef.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/IRBuilder.h>
#include <vector>
#include <string>
int main()
{
llvm::LLVMContext context;
llvm::Module *module = new llvm::Module("myModule", context);
llvm::IRBuilder<> builder(context);
llvm::FunctionType *funcType = llvm::FunctionType::get(builder.getVoidTy(), false);
llvm::Function *mainFunc =
llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "main", module);
llvm::BasicBlock *entry = llvm::BasicBlock::Create(context, "entrypoint", mainFunc);
builder.SetInsertPoint(entry);
llvm::Value *helloWorld = builder.CreateGlobalStringPtr("hello world!\n");
std::vector<llvm::Type *> putsArgs;
putsArgs.push_back(builder.getInt8Ty()->getPointerTo());
llvm::ArrayRef<llvm::Type*> argsRef(putsArgs);
llvm::FunctionType *putsType =
llvm::FunctionType::get(builder.getInt32Ty(), argsRef, false);
llvm::FunctionCallee putsFunc = module->getOrInsertFunction("puts", putsType);
builder.CreateCall(putsFunc, helloWorld);
builder.CreateRetVoid();
module->print(llvm::errs(), nullptr);
}
A side question: BTW, when I am searching for LLVM examples, a lot of results are IR examples. How can I get the results to teach creating from C++?

Related

Using JIT in llvm (ExecutionEngine create error) C++

I'm trying to use public example of compiling and running function from llvm bitcode, but it doesn't work (I'm using the last version of llvm)
Here is my code
#pragma warning(disable : 4146)
#include <iostream>
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Verifier.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
using namespace llvm;
int main(int argc, char* argv[]) {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
llvm::LLVMContext context;
std::unique_ptr<llvm::Module> m{ new llvm::Module {"test", context} };
Constant* init_value = ConstantInt::get(Type::getInt32Ty(context), APInt(32, 12));
GlobalVariable* bsp = new GlobalVariable(*m, Type::getInt32Ty(context), false, GlobalValue::ExternalLinkage, init_value, "bsp", 0/*, GlobalValue::GeneralDynamicTLSModel*/);
llvm::FunctionType* funcType = llvm::FunctionType::get(Type::getInt32Ty(context), {}, false);
llvm::Function* mainFunc = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "main", m.get());
llvm::BasicBlock* bb = llvm::BasicBlock::Create(context, "entrypoint", mainFunc);
IRBuilder<> builder(bb);
builder.CreateRet(builder.CreateLoad(bsp));
std::string err;
llvm::EngineBuilder EB(std::move(m));
EB.setEngineKind(llvm::EngineKind::JIT).setErrorStr(&err);
llvm::ExecutionEngine* EE = EB.create();
if (!EE) {
std::cerr << "unable to create a jitter: " << err << "\n";
return 0;
}
EE->finalizeObject();
const auto fa = (int(*)())EE->getFunctionAddress("main");
printf("%d\n", fa());
system("pause");
}
I can compile and build but this error appears at startup
unable to create a jitter: JIT has not been linked in.
I looked on the internet to find a solution to this problem, it was said that the file MCJIT.h needed to be included, but the code shows that it is included. And it also crash me on end of the function. Like i can use this code in the other function, but it will trigger a Visual Studio breakpoint at the exit of the function
EDIT:
I tried calling the LLVMLinkInMCJIT() function, this gave no result and I saw the following in my binary.
00007FF7C0D1AA96 | FF15 FC961A00 | call qword ptr ds:[<&LLVMLinkInInterpreter>]
LLVMLinkInInterpreter function code
00007FF8BCB6EC30 | C2 0000 | ret 0x0
Look like I need to rebuild my llvm-c.dll, I'll try it and tell you what happens

LLVM 8 and later ORC JIT problems with math library

Since LLVM 8 (including current LLVM trunk, aka LLVM 9) I run into a problem when using the ORC JIT ExecutionEngine with functions which contain a call to the standard math library.
The JIT compiler is able to find the symbol for the function but fails to get the address for it in case the function makes a call to the math library.
I attach a simple exploit that shows the problem. The program test.cc reads in an IR file which contains a single function in LLVM's Intermediate Representation:
The function takes a single argument, a floating point number, and returns in case of
"func_works.ll" the argument itself, and in case of
"func_cos_fails.ll" the cosine of the argument.
I didn't implement the choice between the two files at runtime, so the program needs to be rebuilt when switching to the other case.
The program uses the standard KaleidoscopeJIT.h that comes with LLVM (except that I had to expose the Datalayout).
If you build the program with the "func_works.ll" and run it, the program succeeds with:
symbol found!
address found!
If you build the program with the "func_cos_fails.ll" and run it, the program fails with:
symbol found!
Failure value returned from cantFail wrapped call
UNREACHABLE executed at install/llvm-8.0-x86-debug/include/llvm/Support/Error.h:732!
This happens with LLVM 8 release and the current LLVM trunk.
Does anyone see what's going on?
This test was run on an x86 Linux Ubuntu system with LLVM configured with
cmake -G "Unix Makefiles" \
-DBUILD_SHARED_LIBS="ON" \
-DLLVM_ENABLE_RTTI="ON" \
-DLLVM_ENABLE_ZLIB="OFF" \
-DLLVM_ENABLE_TERMINFO="OFF" \
-DCMAKE_BUILD_TYPE="Debug" \
-DCMAKE_INSTALL_PREFIX=$CMAKE_INSTALL_PREFIX \
-DLLVM_TARGETS_TO_BUILD="X86" \
$SRC
test.cc:
#include "KaleidoscopeJIT.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/InitLLVM.h"
#include <iostream>
using namespace llvm;
using namespace llvm::orc;
int main(int argc, char **argv) {
InitLLVM X(argc, argv);
EnableDebugBuffering = true;
LLVMContext Context;
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
cl::ParseCommandLineOptions(argc, argv, "Kaleidoscope example program\n");
SMDiagnostic Err;
std::unique_ptr<llvm::Module> M = parseIRFile( "func_cos_fails.ll" , Err, Context, false);
//std::unique_ptr<llvm::Module> M = parseIRFile( "func_works.ll" , Err, Context, false);
if (!M) {
Err.print("IR parsing failed: ", errs());
return 0;
}
std::unique_ptr<KaleidoscopeJIT> TheJIT;
TheJIT = llvm::make_unique<KaleidoscopeJIT>();
auto H = TheJIT->addModule(std::move(M));
std::string MangledName;
llvm::raw_string_ostream MangledNameStream(MangledName);
llvm::Mangler::getNameWithPrefix(MangledNameStream, "func_ir" , TheJIT->getDL() );
if (auto Sym = TheJIT->findSymbol(MangledNameStream.str()))
{
std::cout << "symbol found!\n";
void* fptr = (void *)cantFail(Sym.getAddress());
std::cout << "address found!\n";
}
else
{
std::cout << "symbol not found!\n";
}
return 0;
}
func_cos_fails.ll:
source_filename = "module"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
declare float #cosf(float)
define float #func_ir(float %arg0) {
entrypoint:
%0 = call float #cosf(float %arg0)
ret float %0
}
func_works.ll:
source_filename = "module"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define float #func_ir(float %arg0) {
entrypoint:
ret float %arg0
}
KaleidoscopeJIT.h:
#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <vector>
namespace llvm {
namespace orc {
class KaleidoscopeJIT {
public:
using ObjLayerT = LegacyRTDyldObjectLinkingLayer;
using CompileLayerT = LegacyIRCompileLayer<ObjLayerT, SimpleCompiler>;
KaleidoscopeJIT()
: Resolver(createLegacyLookupResolver(
ES,
[this](const std::string &Name) {
return ObjectLayer.findSymbol(Name, true);
},
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
ObjectLayer(ES,
[this](VModuleKey) {
return ObjLayerT::Resources{
std::make_shared<SectionMemoryManager>(), Resolver};
}),
CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
}
TargetMachine &getTargetMachine() { return *TM; }
VModuleKey addModule(std::unique_ptr<Module> M) {
auto K = ES.allocateVModule();
cantFail(CompileLayer.addModule(K, std::move(M)));
ModuleKeys.push_back(K);
return K;
}
void removeModule(VModuleKey K) {
ModuleKeys.erase(find(ModuleKeys, K));
cantFail(CompileLayer.removeModule(K));
}
JITSymbol findSymbol(const std::string Name) {
return findMangledSymbol(mangle(Name));
}
const DataLayout& getDL() const {
return DL;
}
private:
std::string mangle(const std::string &Name) {
std::string MangledName;
{
raw_string_ostream MangledNameStream(MangledName);
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
}
return MangledName;
}
JITSymbol findMangledSymbol(const std::string &Name) {
#ifdef _WIN32
// The symbol lookup of ObjectLinkingLayer uses the SymbolRef::SF_Exported
// flag to decide whether a symbol will be visible or not, when we call
// IRCompileLayer::findSymbolIn with ExportedSymbolsOnly set to true.
//
// But for Windows COFF objects, this flag is currently never set.
// For a potential solution see: https://reviews.llvm.org/rL258665
// For now, we allow non-exported symbols on Windows as a workaround.
const bool ExportedSymbolsOnly = false;
#else
const bool ExportedSymbolsOnly = true;
#endif
// Search modules in reverse order: from last added to first added.
// This is the opposite of the usual search order for dlsym, but makes more
// sense in a REPL where we want to bind to the newest available definition.
for (auto H : make_range(ModuleKeys.rbegin(), ModuleKeys.rend()))
if (auto Sym = CompileLayer.findSymbolIn(H, Name, ExportedSymbolsOnly))
return Sym;
// If we can't find the symbol in the JIT, try looking in the host process.
if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
#ifdef _WIN32
// For Windows retry without "_" at beginning, as RTDyldMemoryManager uses
// GetProcAddress and standard libraries like msvcrt.dll use names
// with and without "_" (for example "_itoa" but "sin").
if (Name.length() > 2 && Name[0] == '_')
if (auto SymAddr =
RTDyldMemoryManager::getSymbolAddressInProcess(Name.substr(1)))
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
#endif
return nullptr;
}
ExecutionSession ES;
std::shared_ptr<SymbolResolver> Resolver;
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
ObjLayerT ObjectLayer;
CompileLayerT CompileLayer;
std::vector<VModuleKey> ModuleKeys;
};
} // end namespace orc
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
for convenience I provide a Makefile:
LLVM_CONFIG = ${LLVM_INSTALL_PATH}
LLVM_CXXFLAGS = $(shell $(LLVM_CONFIG) --cxxflags)
LLVM_LDFLAGS = $(shell $(LLVM_CONFIG) --ldflags)
LLVM_LIBS = $(shell $(LLVM_CONFIG) --libs)
all: test
test.o: test.cc KaleidoscopeJIT.h
g++ -c -o $# $< $(LLVM_CXXFLAGS)
test: test.o
g++ -o $# $< $(LLVM_LDFLAGS) $(LLVM_LIBS)
clean:
rm -f *.o
rm -f test
I believe the solution to this (for llvm 7 and 8 anyway) was found here:
https://stackoverflow.com/a/56862433/2310373
Namely, replace:
[this](const std::string &Name) {
return ObjectLayer.findSymbol(Name, true);
},
With something like
[this](const std::string &Name) {
auto FoundSymbol = ObjectLayer.findSymbol(Name, true);
if (!FoundSymbol) {
if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
}
return FoundSymbol;
},

Why is my LLVM JIT implementation segfaulting?

I'm trying to implement a simple JIT compiler using LLVM, following along with the tutorial (http://releases.llvm.org/4.0.1/docs/tutorial/BuildingAJIT1.html), and I'm running into a segfault. I've rewritten my code in the form a minimal (albeit still kinda long) example. The example loops through the integers 0 through 9 and for each one attempts to compile a function that prints that integer, add it to a module, execute the function, and then remove the module from the JIT. This is to simulate an interactive session in which a user inputs commands such as print 0, print 1, etc.
#include <array>
#include <cstdint>
#include <iostream>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/JITSymbol.h>
#include <llvm/ExecutionEngine/Orc/CompileUtils.h>
#include <llvm/ExecutionEngine/Orc/IRCompileLayer.h>
#include <llvm/ExecutionEngine/Orc/LambdaResolver.h>
#include <llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/ExecutionEngine/RuntimeDyld.h>
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/GlobalValue.h>
#include <llvm/IR/GlobalVariable.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/IR/Mangler.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Type.h>
#include <llvm/IR/Value.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Support/DynamicLibrary.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm/Transforms/Scalar/GVN.h>
#include <memory>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
int main() {
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
llvm::InitializeNativeTargetAsmParser();
auto machine = llvm::EngineBuilder().selectTarget();
llvm::orc::ObjectLinkingLayer<> linking_layer;
llvm::orc::IRCompileLayer<llvm::orc::ObjectLinkingLayer<>> compile_layer(
linking_layer, llvm::orc::SimpleCompiler(*machine)
);
llvm::LLVMContext context;
llvm::IRBuilder<> builder(context);
auto layout = machine->createDataLayout();
auto module = std::make_unique<llvm::Module>("module", context);
auto manager = std::make_unique<llvm::legacy::FunctionPassManager>(
module.get()
);
for (
auto p : {
llvm::createInstructionCombiningPass(),
llvm::createReassociatePass(), llvm::createGVNPass(),
llvm::createCFGSimplificationPass()
}
) manager->add(p);
module->setDataLayout(layout);
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
auto index = llvm::ConstantInt::get(context, llvm::APInt(8, 0));
std::vector<llvm::Constant*> indices = {index, index};
std::string func_name = "func";
for (auto i = 0; i < 10; ++i) {
auto format_str = new llvm::GlobalVariable(
*module, llvm::ArrayType::get(llvm::Type::getInt8Ty(context), 4),
true, llvm::GlobalValue::PrivateLinkage,
llvm::ConstantDataArray::getString(context, "%i\n"), "format_str"
);
format_str->setAlignment(1);
auto function = llvm::Function::Create(
llvm::FunctionType::get(
llvm::Type::getVoidTy(context), std::vector<llvm::Type*>{},
false
), llvm::Function::ExternalLinkage, func_name, module.get()
);
builder.SetInsertPoint(
llvm::BasicBlock::Create(context, "entry", function)
);
builder.CreateCall(
module->getOrInsertFunction(
"printf", llvm::FunctionType::get(
llvm::IntegerType::getInt32Ty(context),
llvm::PointerType::get(llvm::Type::getInt8Ty(context), 0),
true
)
), std::vector<llvm::Value*>{
llvm::ConstantExpr::getGetElementPtr(
nullptr, format_str, indices
), llvm::ConstantInt::get(context, llvm::APInt(32, i))
}, "call"
);
builder.CreateRetVoid();
std::string message;
llvm::raw_string_ostream message_stream(message);
if (llvm::verifyFunction(*function, &message_stream))
throw std::runtime_error(message_stream.str());
auto handle = compile_layer.addModuleSet(
std::array<std::unique_ptr<llvm::Module>, 1>{std::move(module)},
std::make_unique<llvm::SectionMemoryManager>(),
llvm::orc::createLambdaResolver(
[&](const std::string& name) {
auto symbol = compile_layer.findSymbol(name, false);
return symbol ? symbol : llvm::JITSymbol(nullptr);
}, [](const std::string& name) {
auto address = llvm::RTDyldMemoryManager::
getSymbolAddressInProcess(name);
return address ? llvm::JITSymbol(
address, llvm::JITSymbolFlags::Exported
) : llvm::JITSymbol(nullptr);
}
)
);
std::string mangled_name;
llvm::raw_string_ostream mangled_name_stream(mangled_name);
llvm::Mangler::getNameWithPrefix(
mangled_name_stream, func_name, layout
);
(
reinterpret_cast <void(*)()> (
static_cast <intptr_t> (
compile_layer.findSymbol(
mangled_name_stream.str(), true
).getAddress()
)
)
)();
compile_layer.removeModuleSet(handle);
}
}
The expected output is as follows.
0
1
2
3
4
5
6
7
8
9
Instead I get this.
0
Segmentation fault (core dumped)
According to GDB, the segfault is occuring during the call to llvm::GlobalVariable::GlobalVariable. Here's the backtrace.
#0 0x00007ffcdb8b6541 in llvm::GlobalVariable::GlobalVariable(llvm::Module&, llvm::Type*, bool, llvm::GlobalValue::LinkageTypes, llvm::Constant*, llvm::Twine const&, llvm::GlobalVariable*, llvm::GlobalValue::ThreadLocalMode, unsigned int, bool) () from /usr/lib/libLLVM-4.0.so
#1 0x000000010000698a in main () at main.cc:83
I'm using LLVM version 4.0.1 and GCC version 7.1.1 and compiling with the following command.
g++ -std=c++17 main.cc -o main -O0 -Wall -Wextra -Wno-unused-function \
-Wno-unused-value -Wno-unused-parameter -Werror -ggdb \
`llvm-config --system-libs --libs core`
I'm hoping some LLVM veteran can find my mistake. Thanks, guys!
module is initialized before the for loop:
auto module = std::make_unique<llvm::Module>("module", context);
then in the for loop:
for(...)
{
auto format_str = new llvm::GlobalVariable(*module, ...);
^~~~~~~
...
std::array<std::unique_ptr<llvm::Module>, 1>{std::move(module)},
^~~~~~~~~~~~~~~~~
}
At first iteration you access the object owned by module (ok) and then move from it. This will transfer the ownership of the managed object away from module.
At the second iteration you access the object managed by module -> crash (because it doesn't have a managed object anymore)

Static C++ Variable Apple Mach-o Linker issue

I am working on an Ogre project and I am getting some issues with Xcode.
Whenever I make the scene manager pointer static, the program does not compile and I get the following error:
Undefined symbols for architecture x86_64:
"OgreInit::sceneManager", referenced from:
OgreInit::initOgre() in OgreInit.o
OgreInit::initScene() in OgreInit.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Here is my OgreInit.cpp
#include <iostream>
#include <exception>
#include <string>
#include "OGRE/Ogre.h"
#include "OGRE/OgreException.h"
#include "OGRE/OgreRoot.h"
#include "OGRE/OgreResourceManager.h"
#include "OGRE/OgreMath.h"
#include "MainLoop.h"
#include "WorkingDirectory.h"
#include "OgreInit.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include "macUtils.h"
#endif
OgreInit::OgreInit()
{
mainLoop = new MainLoop();
mainLoop->startLoop();
initOgre();
initScene();
}
void OgreInit::initOgre()
{
root = new Ogre::Root(WorkingDirectory::getResourcesDirectory() + "plugins.cfg", WorkingDirectory::getResourcesDirectory() + "window.cfg", "");
root->showConfigDialog();
window = root->initialise(true);
sceneManager = root->createSceneManager(Ogre::ST_GENERIC);
camera = sceneManager->createCamera("mainCamera");
camera->setNearClipDistance(0.1);
camera->setFarClipDistance(300);
camera->setPosition(0, 0, 80);
//camera->lookAt(Ogre::Vector3::ZERO);
cameraNode = sceneManager->getRootSceneNode()->createChildSceneNode();
cameraNode->attachObject(camera);
viewport = window->addViewport(camera);
viewport->setClearEveryFrame(true);
viewport->setAutoUpdated(true);
viewport->setBackgroundColour(Ogre::ColourValue(1, 0, 1));
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(WorkingDirectory::getModelDirectory(), "FileSystem");
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
void OgreInit::initScene()
{
sceneManager->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));
Ogre::Entity *ogreHead = sceneManager->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode *headNode = sceneManager->getRootSceneNode()->createChildSceneNode("HeadNode");
headNode->attachObject(ogreHead);
headNode->rotate(*new Ogre::Vector3(0, 1, 0), (Ogre::Radian)Ogre::Math::DegreesToRadians(90));
Ogre::Light *light = sceneManager->createLight("MainLight");
light->setPosition(20.0f, 80.0f, 50.0f);
}
//init resources before scene :! and translate before attaching
OgreInit::~OgreInit()
{
}
And of course the header:
#ifndef __OgreTest__OgreInit__
#define __OgreTest__OgreInit__
#include <iostream>
#include <string>
#include <memory>
#include "OGRE/Ogre.h"
#include "MainLoop.h"
class OgreInit
{
public:
OgreInit();
~OgreInit();
private:
void initOgre();
void initScene();
MainLoop *mainLoop;
Ogre::Root *root;
Ogre::RenderWindow *window;
static Ogre::SceneManager *sceneManager;
Ogre::Viewport *viewport;
Ogre::Camera *camera;
Ogre::SceneNode *cameraNode;
};
#endif /* defined(__OgreTest__OgreInit__) */
I have seen this issue on Stackoverflow quite often, but usually it happened because some required libraries were not included. I don't think that is the issue here because I am not getting any errors if I change: static Ogre::SceneManager *sceneManager; to: Ogre::SceneManager *sceneManager;
Thanks in advance.
As well as declaring it in your header file, you need to actually define the sceneManager in your implementation file:
...
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include "macUtils.h"
#endif
Ogre::SceneManager *OgreInit::sceneManager = 0;
OgreInit::OgreInit()
{
...

embedding python in c++

I created a VCL Application in c++, borland. In my project there is a file where I have implemented embedded python in the methods defined in the same(my application contains a button which calls the method in which embedded python is implemented). when I compile, my build is successful. but when I run my application, and click on the button it shows the run time error : "Access violation at address 1E091375 in module 'PYTHON25.DLL'. Read of address 00000004" . please help.
I have never used Python before.
my program:
#pragma hdrstop
#include <fstream>
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "Python.h"
#include "Unit1.h"
#include "Unit2.h"
#pragma link "python25_bcpp.lib"
//---------------------------------------------------------------------------
#pragma package(smart_init)
bool callHelloWorld(int intVal)
{
char fName[] = "Hello"; //file name
char cFunc[] = "hello"; //method name
char *pfName, *pcFunc;
PyObject *pName, *pModule, *pDict, *pFunc ;
pfName = fName;
pcFunc = cFunc;
Py_Initialize();
pName = PyString_FromString(pfName);
pModule = PyImport_Import(pName);
pDict = PyModule_GetDict(pModule);
pFunc = PyDict_GetItemString(pDict, pcFunc);
if (PyCallable_Check(pFunc))
{
PyObject_CallObject(pFunc, NULL);
} else
{
PyErr_Print();
}
// Py_DECREF(pModule);
// Py_DECREF(pName);
Py_Finalize();
return 0;
}
Check the return values of PyImport_Import (is the module in the search path?) and PyDict_GetItemString.
If that doesn't help put some trace messages in your app to see where it crashes.
This works for me:
Just delete Py_Finalize()
I read in another site that Py_Finalize has some problems in specific cases such as threading.