I would like to read some variable's value in Matlab from c++. I searched in Internet and found out below example in Matlab Documentation Page.
for using this example I Did below steps:
I add this include path to project :
c:\program files\Matlab\r2017b\extern\include
then I Add this path Library Directory :
c:\program Files\Matlab\r2017b\extern\lib\win64\microsoft
then I Add this library to project :
"libMatlabEngine.lib"
"libMatlabDataArray.lib"
then I placed needed DLLs beside application EXE file.
then I ran the application after that application faced with access violataion error when startMATLAB() Method has been ran.
Note: I had other problem that I resolved it. but I think that problem was very strange and may be knowing that problem help you to find main reason of my problems.
problem was : when I set dll's files path in environment variables my app didn't find dlls and get "no entry point to *.dll" run time error. but when I copy dlls beside of exe, my app saw them.(I restarted VS2013 after change environment variables.)
#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include <iostream>
void callgetVars() {
using namespace matlab::engine;
// Start MATLAB engine synchronously
std::unique_ptr<MATLABEngine> matlabPtr = startMATLAB();
// Evaluate MATLAB statement
matlabPtr->eval(convertUTF8StringToUTF16String("[az,el,r] = cart2sph(5,7,3);"));
// Get the result from MATLAB
matlab::data::TypedArray<double> result1 = matlabPtr->
getVariable(convertUTF8StringToUTF16String("az"));
matlab::data::TypedArray<double> result2 = matlabPtr->
getVariable(convertUTF8StringToUTF16String("el"));
matlab::data::TypedArray<double> result3 = matlabPtr->
getVariable(convertUTF8StringToUTF16String("r"));
// Display results
std::cout << "az: " << result1[0] << std::endl;
std::cout << "el: " << result2[0] << std::endl;
std::cout << "r: " << result3[0] << std::endl;
}
I use vs2013 and Matlab 2017b in windows 7.
Thanks for your help.
Related
I am trying to use OCCI to connect my program to an oracle database but I am getting an SQLException 32104 when I try the createEnvironment function.
My code:
#include <OpenXLSX.hpp>
#include <occi.h>
#include <string>
using namespace OpenXLSX;
using namespace oracle::occi;
int main() {
std::string user = "";
std::string pass = "";
std::string conn_str = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.2.159)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=test)))";
std::cout << "Initializing Database Connection ......" << std::endl;
try {
Environment* env = Environment::createEnvironment(Environment::DEFAULT);
//Connection *conn = env->createConnection(user, pass ,conn_str);
} catch(SQLException &e) {
std::cout << "Error Message: " << e.getErrorCode() << std::endl;
std::cout << e.getMessage() << std::endl;
}
std::cout << "Initializing Database Connection ......";
std::cout << " OK" << std::endl;
XLDocument doc;
doc.open("Template.xlsx");
auto wks = doc.workbook().worksheet("Extruder Data Log");
int row_number = 4;
char column_letter = 'A';
char column_letter2 = 'A';
std::string loc;
loc = column_letter;
loc += std::to_string(4);
wks.cell(loc).value() = "Hello, OpenXLSX!";
doc.save();
//env->terminateConnection(conn);
//Environment::terminateEnvironment(env);
std::cout << "Program Terminated: Press Enter ...";
std::string wait;
std::cin >> wait;
return 0;
}
I am using CMake to compile:
cmake_minimum_required(VERSION 3.15)
project(Atlas)
set(CMAKE_CXX_STANDARD 17)
# Set the build output location to a common directory
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output)
set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include/lib)
add_subdirectory(OpenXLSX)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/include/OpenXLSX/headers)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/include/OpenXLSX)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/include/OCCI)
link_directories(${CMAKE_PREFIX_PATH})
find_package(OpenXLSX REQUIRED)
find_library(OCCI NAMES oraocci21.lib oci.lib oramysql.lib oraocci21d.lib ociw32.lib)
add_executable(Atlas Atlas.cpp)
target_link_libraries(Atlas OpenXLSX::OpenXLSX)
target_link_libraries(Atlas ${OCCI})
I have the dlls in the output directory where the executable and libraries end up outputting to.
I figure that it should run, but I am getting a Microsoft C++ exception: oracle::occi::SQLException
and on debugging it shows that it is message 32104 which I know means that it cannot get the error.
The Debug window show that it loads the oraocci21.dll but not any of the other OCCI dlls.
If anyone can let me know what I'm doing wrong I would be incredibly grateful since I have scoured the internet trying to figure this out.
EDIT
Figured out this error, I hadn't moved all of the dlls from the instant client. I was only including the dlls that corresponded to the library names.
I included ocijdbc21.dll, orannzsbb.dll, and oraociicus.dll to the folder with my executable and it now runs past the createEnvironment(Environment::DEFAULT) part.
With this edit, though, I am now running into Error 24960 which says that OCI_ATTR_USERNAME is more than length 255 which it is not.
If anyone can help with that please let me know but I hope that anyone else running across this who needs help sees the part about the dlls.
If it helps to answer my question, I am using instant client base 21_3 and sdk 21_3. I am also using MSVC 16 2019 for compilation with C++17 as the version of C++. My Oracle Database is running on 19c and I can connect to it remotely.
So I figured it out.
I was using this command for cmake:
cmake --build . --target ALL_BUILD --config Debug
This release config command should work because I have debugged the program:
cmake --build . --target ALL_BUILD --config Release
For some reason, I can only assume that OCCI did not like my debugger
version or something like that. If someone could please comment on why this happens I would like to learn.
Asking this because i can't figure it out.
Environment: Windows 10 x64, Qt Creator 4.11.1, OpenCv 3.9, msvc 2017_64
I tried this as like the Qt Documentation says:
QList<QCameraInfo> availableCameras = QCameraInfo::availableCameras();
for (const QCameraInfo &cameraInfo : availableCameras) {
std::cout << cameraInfo.description().toStdString() << std::endl;
}
if(availableCameras.isEmpty())
cout << availableCameras.size() << endl;
cout << "Empty" << endl;
But in output i get: "0, empty"
I don't know if it's a bug, but with another blank project without including OpenCv this code works. Can someone explain?
-EDIT-
I solved the problem deleting the directory
"build-ProjectName-Desktop_Qt_5_14_1_MSVC2017_64bit-Release"
So, i rebuilding and deploying with "windeployqt.exe ." in the directory of my project.exe
I need to write c++ program which sets path using system() function:
system("set PATH=%PATH%;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64");
system("nvcc -x cu -o cudapair cudapair.c");
But it doesnt work. It throws error, because path wasn't set. What's the problem?
I need to write c++ program which sets path using system() function
I'm assuming what you actually need to do is write a C++ program that
sets the PATH for the environment in which it will then execute
nvcc -x cu -o cudapair cudapair.c
You think you need to make that environment setting with
the system function, but in fact you don't.
You should understand that a process cannot change its own environment.
A process inherits its environment from its parent process, and it
can change the environment that is inherited by its child processes.
That's why your posted attempt does not work.
system("set PATH=%PATH%;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64");
executes a child process of your program. That child process gets the same environment settings
as your program, and can't change them. What does that child process do? It invokes the
Windows shell to run the commandline:
set PATH=%PATH%;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64");
This would change the environment settings of any more child processes that were started
by this commandline. But there aren't any. The commandline makes an environment setting
that no process uses. Your system call returns. That environment setting no longer
exists anywhere. Nothing has changed.
You then call:
system("nvcc -x cu -o cudapair cudapair.c");
which starts a second child process, again with the same environment settings that your
program started with.
What you should do
Get the value of PATH from the environment that your program inherits.
Using that value, create the new value of PATH that you want to pass to your child process.
Put that new value of PATH into the environment your child process will inherit.
Run your child process.
You use system only to do 4.
To do 1, use the Microsoft C library function getenv_s
(It is a secure variant of the Standard C++ std::getenv)
To do 3, use the Microsoft C library function _putenv_s (Note the leading underscore.)
Here is an illustrative program for Visual C++:
#include <iostream>
#include <string>
#include <cstdlib>
const std::size_t ENV_BUF_SIZE = 1024; // Enough for your PATH?
int main()
{
char buf[ENV_BUF_SIZE];
std::size_t bufsize = ENV_BUF_SIZE;
int e = getenv_s(&bufsize,buf,bufsize,"PATH");
if (e) {
std::cerr << "`getenv_s` failed, returned " << e << '\n';
exit(EXIT_FAILURE);
}
std::string env_path = buf;
std::cout << "In main process, `PATH`=" << env_path << std::endl;
env_path += ";C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64";
e = _putenv_s("PATH",env_path.c_str());
if (e) {
std::cerr << "`_putenv_s` failed, returned " << e << std::endl;
exit(EXIT_FAILURE);
}
std::cout << std::endl;
e = std::system("echo \"In child process `PATH`=%PATH%\"");
if (e) {
std::cerr << "`std::system` failed, returned " << e << std::endl;
exit(EXIT_FAILURE);
}
return 0;
}
See it live
I want to have my DLL's in a subdirectory of the directory where my executable is. My current directory looks like:
Main Folder: [Folder]
Program.exe
sfml.dll
Assets [Folder]
Picture.png
Music.wav
When I really want it to look like:
Main Folder: [Folder]
Program.exe
Assets [Folder]
Picture.png
Music.wav
MyDlls[Folder]
sfml.dll
When I try to put them (DLL's) in a folder I get the error message:
The program can't start because sfml-system-d-2.dll is missing from your computer. Try reinstalling the program to fix this problem.
So, then I looked into explicit linking, and followed the tutorial here:
http://www.dreamincode.net/forums/topic/118076-dlls-explicit-linking/
If explicit linking is not what I need to use, then please tell me what I need to do. Else, please tell me what is wrong with my code below: (Also, I do not know if this is static or dynamic linking..??)
// Startup.h
#ifndef STARTUP_H
#define STARTUP_H
#include <iostream>
#include <windows.h>
class Startup
{
private:
HINSTANCE hDLL;
public:
// Explicitly link SFML DLL's
typedef int(*funcAdd) (int, int);
typedef int(*funcSubtract) (int, int);
void LoadDLLs()
{
// Retrieve DLL handle.
vector<LPCSTR> libraries = {"openal32.dll",
"sfml-audio-2.dll",
"sfml-audio-d-2.dll",
"sfml-graphics-2.dll",
"sfml-graphics-d-2.dll",
"sfml-system-2.dll",
"sfml-system-d-2.dll",
"sfml-window-2.dll",
"sfml-window-d-2.dll"};
for (int i = 0; i < libraries.size(); i++)
{
hDLL = LoadLibrary(libraries[i]);
if (hDLL == NULL)
{
std::cout << "Failed to load library.\n";
}
else
{
funcAdd Add = (funcAdd)GetProcAddress(hDLL, "Add");
funcSubtract Subtract = (funcSubtract)GetProcAddress(hDLL, "Subtract");
if (Add)
std::cout << "10+10=" << Add(10, 10) << std::endl;
if (Subtract)
std::cout << "50-10=" << Subtract(50, 10) << std::endl;
FreeLibrary(hDLL);
}
std::cin.get();
}
};
#endif
You could register an App Path (see link), making sure you add your Applications alternate DLL folder location to the App Path PATH value.
You cannot do what you want directly. The code you attached will work only for dynamic loading dlls, but it is not the case.
What you want to do will be platform specific and you need to set the path for the library before executing the program.
I am struggling with an issue regarding running a SQL statement to an Oracle database through C++, using occi. My code is as follows:
#include <iostream>
#include "occi.h"
namespace oc = oracle::occi;
int main() {
std::cout << "Setting up environment...\n";
oc::Environment * env = oc::Environment::createEnvironment();
std::cout << "Setting up connection...\n";
oc::Connection * conn = env->createConnection("user","pass","server");
std::cout << "Creating statement...\n";
//Very simply query...
oc::Statement * stmt = conn->createStatement("SELECT '1' FROM dual");
std::cout << "Executing query...\n";
oc::ResultSet * rs = stmt->executeQuery();
while(rs->next()) {
std::cout << rs->getString(1) << std::endl; //Error is thrown at this line, but after printing since I can see '1' on the console.
}
stmt->closeResultSet(rs);
conn->terminateStatement(stmt);
env->terminateConnection(conn);
oc::Environment::terminateEnvironment(env);
return 0;
}
The error that is shown is:
Unhandled exception at 0x1048ad7a (msvcp100d.dll) in MyDatabaseApp.exe: 0xC0000005: Access violation reading location 0xccccccd0.
My program stops inside 'xstring' at the following line of code:
#if _ITERATOR_DEBUG_LEVEL == 0
....
#else /* _ITERATOR_DEBUG_LEVEL == 0 */
typedef typename _Alloc::template rebind<_Elem>::other _Alty;
_String_val(_Alty _Al = _Alty())
: _Alval(_Al)
{ // construct allocator from _Al
....
}
~_String_val()
{ // destroy the object
typename _Alloc::template rebind<_Container_proxy>::other
_Alproxy(_Alval);
this->_Orphan_all(); //<----------------------Code stops here
_Dest_val(_Alproxy, this->_Myproxy);
_Alproxy.deallocate(this->_Myproxy, 1);
this->_Myproxy = 0;
}
#endif /* _ITERATOR_DEBUG_LEVEL == 0 */
If I change my query to:
oc::Statement * stmt = conn->createStatement("SELECT 1 FROM dual");
and the loop statement to:
std::cout << rs->getInt(1) << std::endl;
It works fine with no errors. I think this is because getting an integer simply returns a primitive, but when an object is being returned it is blowing up (I think on a destructor, but I'm not sure why...)
I have been playing around with this for hours today, and I am pretty stuck.
Some information about my system:
OS - Windows XP
Oracle Version - 10g
IDE - Microsoft Visual Studio 2010 Express C++
My project properties are as follows:
C/C++ - General - Additional Include Directories = C:\oracle\product\10.2.0\client_1\oci\include;%(AdditionalIncludeDirectories)
C/C++ - Code Generation - Multi-threaded Debug DLL (/MDd)
Linker - General - Additional Library Directories = C:\oracle\product\10.2.0\client_1\oci\lib\msvc\vc8;%(AdditionalLibraryDirectories)
Linked - Input - Additional Dependencies = oraocci10.lib;oraocci10d.lib;%(AdditionalDependencies)
I hope I haven't been confusing with too much info... Any help or insight would be great, Thanks in advance!
EDIT If I rewrite my loop, storing the value in a local variable, the error is thrown at the end of the loop:
while(rs->next()) {
std::string s = rs->getString(1); //s is equal to "1" as expected
std::cout << s << std::endl; //This is executed successfully
} //Error is thrown here
Usually such kind of problems come from differences in build environments (IDE) of end user and provider.
Check this.
Related problems:
Unhandled exception at 0x523d14cf (msvcr100d.dll)?
Why does this program crash: passing of std::string between DLLs
First try to use correct lib and dll. If compiled in debug mode then all libs and dlls must be debug. Use VC++ Modules view to be sure that proper DLL loaded.
I was lucky with my application to have all libs compiled for MSVC2010. So I just check debug and release mode DLLs and got working application.
I revisited this issue about a month ago and I found that the MSVC2010 occi library was built for Oracle 11g. We are running Oracle 10g, so I had to use the MSVC2005 library. So I installed the outdated IDE and loaded the Debug library and it worked (for some reason the release version wouldn't work though).
EDIT
For anyone who is having the same problem I was, if downgrading the IDE from MSVC2010 to MSVC2005 with the appropriate libraries doesn't work, you could try upgrading the Oracle client from 10g to 11g and use the MSVC2010 library, as suggested by harvyS. In retrospect this would've probably been the better solution.