I recently tried to create a program that can read an ODBC database then write the entries in an Excel file by using the CRecordset class, the program complilates perfectly, but the problems come in the execution...
First error :
Debug Assertion Failed!
Program: C:\Windows\system32\mfc140ud.dll
File: f:\dd\vctools\vc7libs\ship\atlmfc\include\afxwin1.inl
Line: 24
Second error :
Debug Assertion Failed!
Program: C:\Windows\system32\mfc140ud.dll
File: f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\dbcore.cpp
Line: 3312
The two errors are pointing toward the mfc140ud.dll file, it's not a missing file, so it's not the problem.
Here is the function where the exception is raised:
void parseDB(CRecordset &rs, const CString &SqlString, CString strOut) {
std::cout << "test2";
rs.Open(CRecordset::snapshot, SqlString, CRecordset::readOnly);
std::string entry;
std::fstream file;
std::cout << "test3";
while(!rs.IsEOF()) {
std::cout << "test4";
rs.GetFieldValue((short)0, strOut);
CT2CA pszConvertedAnsiString = strOut;
entry = pszConvertedAnsiString;
writeXLSX(entry.c_str(), file);
rs.MoveNext();
}
rs.Close();
}
The "std::cout << "test"" are here for debugging, and my program generates these errors right after the "test2" display, so I deducted that the error comes from the "Open" line.
This is the way I initialize the CRecordset:
CString sDsn;
CDatabase db;
CRecordset rs(&db);
CString strOut;
CString SqlString;
Then, I use a CALL SQL function in a switch-case:
switch (sequence) {
case 1:
SqlString = "CALL GETCUSNAME(AGENTS)";
break;
case 2:
SqlString = "CALL GETCUSNAME(CLIENT)";
break;
default:
AfxMessageBox(_T("Wrong entry!"));
}
I searched on many sites and I couldn't find an answer, that's why I ask a question here, thanks by advance.
The first assertion comes from AfxGetResourceHandle complaining that it has not been set up correctly.
This will usually happen because you either didn't call AfxWinInit at the start of your application (if you have a console application and didn't set it up with the MFC wizard, this is very likely the case), or you're writing an MFC DLL called from non-MFC code, and you didn't add AFX_MANAGE_STATE(AfxGetStaticModuleState( )); at the start of every externally visible function.
I believe the second is because MFC requires you to wrap CALL queries in curly braces, like so: {CALL GETCUSNAME(AGENTS)}. Otherwise the call is not recognized, and code execution enters a path it is not supposed to take.
Related
I have a simple program that loads a DLL from the current path
#include <iostream>
#include <windows.h>
using namespace std;
auto loaddll(const char * library) {
auto dllModule = LoadLibrary(library);
if(dllModule == NULL)
throw "Can't load dll";
return dllModule;
}
int main() {
try {
auto Handle = loaddll("ISab.dll");
} catch(const char * error) {
cerr << "An Unexpected error :" << error << endl;
cerr << "Get Last Error : " << GetLastError();
}
}
the load library fails for every DLL in the current path but succeeds for DLL like User.dll
if I ran it output will be like
An Unexpected error :Can't load dll
Get Last Error : 0
this also fails if i specify full path to dll
When a Win32 API call fails, and sets the error code, you must call GetLastError before calling any other Win32 API function. You don't do that.
Raising an exception, streaming to cerr etc. are all liable to call other Win32 API functions and so reset the error code.
Your code must look like this:
auto dllModule = LoadLibrary(library);
if (dllModule == NULL)
auto err = GetLastError();
Once you have the error code you should be better placed to understand why the module could not be loaded. Common error codes for LoadLibrary include:
ERROR_MOD_NOT_FOUND which means that the module, or one of its dependencies, cannot be located by the DLL search.
ERROR_BAD_EXE_FORMAT which invariably means a 32/64 bit mismatch, either with the module you load, or one of its dependencies.
what I'm trying to do is integrate a MATLAB-Compiler dll/lib to an new c++ project.
I followed this instruction: How do I integrate my C++ shared Library generated from MATLAB which seams working good (no build errors and intelisense is working good, so it seams all required information are there).
I'm using a very simple mathlab code / function for testing:
function output = extest( arg1,arg2 )
output = arg1+arg2;
end
And the "default" c++ code for matlab functions:
#include "extest.h"
#include <cstdlib>
#include <stdio.h>
int main(int argc, char** argv){
mclmcrInitialize();
if (!mclInitializeApplication(NULL,0)){
std::cerr << "could not initialize the application properly" << std::endl;
return -1;
}
if(!extestInitialize()){
std::cerr << "could not initialize the library properly" << std::endl;
return -1;
}
else{
try{
//code itself (not jet reached therefore removed)
}catch(const mwException& e){
std::cerr << e.what() << std::endl;
return -2;
}
catch(...){
std::cerr << "Unexpected error thrown" << std::endl;
return -3;
}
extestTerminate();
}
mclTerminateApplication();
return 0;
}
After e few moments after the debugger tries to run the line if(!extestInitialize()) the following error gets thrown.
Exception thrown at 0x000002BF72E0EE55 in DllTestingCpp.exe: 0xC0000005: Access violation reading location 0x0000000000000008.
I can hit visual studios continue > button and it is continued after lets say 20x click on it. Starting the code by ctrl + F5 (without debugging) everything is working good.
Any ideas why this happens in debug mode? Or better how I can get rid of this error?
PS: extest is my lib name and using Matlab R2017a 64bit and Visual Studio 2017 (debugging with x64),
The same problem (Matlab2017 + VS 2015) for me.
Probably there is some conflict with java used by MATLAB.
I've fixed it by
const char *args[] = {"-nojvm"};
const int count = sizeof(args) / sizeof(args[0]);
mclInitializeApplication(args, count))
instead of
mclInitializeApplication(NULL,0)
I had the same issue(using VS2019) and I found the following answer here:
https://uk.mathworks.com/matlabcentral/answers/182851-how-do-i-integrate-my-c-shared-library-generated-from-matlab-r2013b-in-visual-studio-2013
I encountered this same issue and reported it to Mathworks. They responded that for VS2013 and later, the debugger is set to break when 0xc0000005 occurs, even though in this case it is handled by the JVM.
The fix is to go to Debug>Windows>Exception Settings>Win32 and uncheck '0xc0000005 Access Violation'. In VS2012, this setting is unchecked by default.
This seems to work o.k.
We developed a dynamic library L.so and an executable X which uses it. Both compiled with debugging info. While running gdb X:
Reading symbols from X...Segmentation fault (core dumped)
The X contains from 4 objects and I found out which one causes the crash. Lets say, if S.cpp is compiled, it crashes in gdb. S.cpp:
class Service {
private:
...
private:
...
LongTaskService longTaskService_; // Implementation is in L.so
If I remove this method from S.cpp, the crash disappears:
bool Service::downloadFile(const string &mapName, int &taskId) {
Properties dProps;
if(!config_.get("downloadService", dProps)) {
LOGG(Logger::ERROR) << "Failed to get config props for downloadService" << Logger::FLUSH;
return false;
}
string url = dProps.get("downloadUrl");
if(url == "") {
LOGG(Logger::ERROR) << "Failed to get url for downloadService" << Logger::FLUSH;
return false;
}
if(url[url.size()-1] != "/")
url += "/";
LOGG(Logger::DEBUG) << "Initializing download from "<< url << mapName << Logger::FLUSH;
URL dUrl(url+mapName);
vector<string> outPath = {workDir_, mapName};
URL outFile(FsUtil::makePath(outPath));
taskId = longTaskService_.submit(DownloadTask::run, dUrl, outFile); // This line causes problems
return true;
}
I wonder why is it like this and can I avoid the crash while debugging?
The usual thing to do here is run "gdb gdb" and then file a bug report with the stack trace.
Another possibility is that you could try updating to a newer version of gdb. That might help.
Anyway it is just a bug. Very new versions of gdb have a bit of protection against some crashes of this sort; but protecting against all crashes is hard.
I am trying to interface with an OEM library. Everything worked on one computer but I am getting lots of problems on another computer.
I the code is throwing a COM exception but I can't figure out the meaning of a error code that doesn't have a ErrorMessage();
The code
#include "stdafx.h"
#include <afx.h>
#include <iostream>
using namespace std;
#import "MTBApi.tlb" named_guids //raw_interfaces_only
using namespace MTBApi;
void DisplayError(_com_error* e)
{
CString message;
// if it is an application error thrown by .NET
if (e->Error() >= 0x80041000)
{
IErrorInfo* info;
BSTR msg;
info = e->ErrorInfo();
info->GetDescription(&msg);
info->Release();
message = CString(msg);
}
// other com errors
else
{
message = e->ErrorMessage();
}
cout << "MTB Error: " << message <<":"<<(unsigned int) e->Error()<< endl;
}
int main(int argc, char **argv)
{
for (int i = 0 ; i < 4 ; i++)
{
IMTBConnectionPtr m_MTBConnection;
try
{
cout <<"1" << endl;
HRESULT a = CoInitializeEx(NULL,COINIT_SPEED_OVER_MEMORY);
cout <<"2" << endl;
m_MTBConnection = IMTBConnectionPtr(CLSID_MTBConnection);
cout <<"3" << endl;
m_MTBConnection->Close();
cout <<"4" << endl;
CoUninitialize();
cout <<"5" << endl;
}
catch(_com_error e)
{
DisplayError(&e);
}
cout << endl;
}
}
The runtime output
1
2
MTB Error: 00000000002205F8:2147746132
1
2
MTB Error: 00000000002205F8:2147746132
1
2
MTB Error: 00000000002205F8:2147746132
1
2
MTB Error: 00000000002205F8:2147746132
Rather Verbose Output from Dependency Walker
http://pastebin.com/7Y33z3Pj
cout << "MTB Error: " << message <<":"<<(unsigned int) e->Error()<< endl;
cout isn't very good at displaying Unicode strings, it merely displays the string pointer value. Not useful of course, use wcout instead. And favor displaying the error code in hex. 0x80040154 is a very common COM error, "Class not registered". Thousands of questions about it already, you just need to get the COM server registered properly. Ask the vendor or author if you don't know how to do that.
00000000002205F8 looks like a memory pointer. You are passing a CString to cout, which only accepts char* or std::string for string values. Maybe the CString contains a Unicode string that is not being converted to Ansi correctly. Also, when calling IErrorInfo::GetDescription(), you are leaking the returned BSTR. You need to free it with SysFreeString() when you are done using it.
Error code 2147746132 (hex 0x80040154) is Severity=FAIL, Facility=FACILITY_ITF, Code=340. FACILITY_ITF typically means the error code is a custom error code defined by the interface that failed. But in this case, 0x80040154 is also a standard error code: REGDB_E_CLASSNOTREG.
If your problem is to rectify the error which you are getting then
then issue is as #Remy pointed out , your com assembly is not registered in the machine you are currently executing your program rather in the other machine it got registered. Register the assembly (for eg COMAssembly.dll which is in C:\ drive) by running the following command in command prompt.
regsvr32 c:\COMAssembly.dll
if its a C++ com assembly , if its a C# assembly register it by using command
regasm c:\COMAssembly.dll
(where regasm can be run in a VS command prompt , otherwise if you are running in normal command prompt then you have to first call vsvars32.bat then call regasm)
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.