I'm trying to convert the functionality of our old code to a DLL.
One of the function wants to export from our old code use a dynamically linked DLL (that I'm gonna call other)
std::wstring otherDLL = L"C:\\PATH\\TO\\OTHER\\DLL"
if (!(libOther = LoadLibraryW(otherDLL.c_str()))){
return;
}
In our old code, this portion of code works just fine.
So I added in my new DLL the following code:
extern "C++" std::wstring test_load(void){
std::wstring otherDLL = L"C:\\PATH\\TO\\OTHER\\DLL"
if (!(libOther = LoadLibraryW(otherDLL.c_str()))){
return L"Not Loaded";
}
return L"Loaded";
}
(this function is not launched during DLLMain). If I try to launch test_load from my DLL in another exe
#include "MyNewDLL.h"
int main()
{
std::wcout << test_load();
}
I get following error
Unhandled exception at 0x7BDE20f3 (ucrtbased.dll) in Test.exe: 0xC00000005: Access violation reading location 0x00000000
What's strange is that if I try to load the OtherDLL from the main that is not inside MyNewDLL, there is no error and I can use it just fine.
Any Idea where my problem could come from ?
Related
In my application I'm using coroutine2 to generate some objects which I have to decode from a stream. These objects are generated using coroutines. My problem is that as soon as I reach the end of the stream and would theoretically throw std::ios_base::failure my application crashes under certain conditions.
The function providing this feature is implemented in C++, exported as a C function and called from C#. This all happens on a 32bit process on Windows 10 x64. Unfortunately it only reliably crashes when I start my test from C# in debugging mode WITHOUT the native debugger attached. As soon as I attach the native debugger everything works like expected.
Here is a small test application to reproduce this issue:
Api.h
#pragma once
extern "C" __declspec(dllexport) int __cdecl test();
Api.cpp
#include <iostream>
#include <vector>
#include <sstream>
#include "Api.h"
#define BOOST_COROUTINES2_SOURCE
#include <boost/coroutine2/coroutine.hpp>
int test()
{
using coro_t = boost::coroutines2::coroutine<bool>;
coro_t::pull_type source([](coro_t::push_type& yield) {
std::vector<char> buffer(200300, 0);
std::stringstream stream;
stream.write(buffer.data(), buffer.size());
stream.exceptions(std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit);
try {
std::vector<char> dest(100100, 0);
while (stream.good() && !stream.eof()) {
stream.read(&dest[0], dest.size());
std::cerr << "CORO: read: " << stream.gcount() << std::endl;
}
}
catch (const std::exception& ex) {
std::cerr << "CORO: caught ex: " << ex.what() << std::endl;
}
catch (...) {
std::cerr << "CORO: caught unknown exception." << std::endl;
}
});
std::cout << "SUCCESS" << std::endl;
return 0;
}
C#:
using System;
using System.Runtime.InteropServices;
namespace CoroutinesTest
{
class Program
{
[DllImport("Api.dll", EntryPoint = "test", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
internal static extern Int32 test();
static void Main(string[] args)
{
test();
Console.WriteLine("SUCCESS");
}
}
}
Some details:
We are using Visual Studio 2015 14 and dynamically link the c++ runtime.
The test library statically links Boost 1.63.0.
We also tried to reproduce this behaviour with calling the functionallity directly from c++ and from python. Both tests have not been successful so far.
If you start the c# code with CTRL F5 (meaning without the .net debugger) everything will also be fine. Only if you start it with F5 (meaning the .NET Debugger attached) the visual studio instance will crash. Also be sure not to enable the native debugger!
Note: If we don't use the exceptions in the stream, everything seams to be fine as well. Unfortunately the code decoding my objects makes use of them and therefore I cannot avoid this.
It would be amazing if you had some additional hints on what might go wrong here or a solution. I'm not entirely sure if this is a boost bug, could also be the c# debugger interfering with boost-context.
Thanks in advance! Best Regards, Michael
I realize this question is old but I just finished reading a line in the docs that seemed pertinent:
Windows using fcontext_t: turn off global program optimization (/GL) and change /EHsc (compiler assumes that functions declared as extern "C" never throw a C++ exception) to /EHs (tells compiler assumes that functions declared as extern "C" may throw an exception).
This is just a guess but in your coroutine I think you are supposed to push a boolean to your sink (named as yield in your code) and the code is not doing it.
I am trying to call cygwin compiled dll in wisual studio environment.
If I compile dll which have function without any library (just return any number),
it works ok, but if I call for example stdio.h, and function with writing file, or just printf function, does not work ( in case of printf function has exited with code 1536).
#include <stdio.h>
int myfunc()
{
char* strtxt = "test";
FILE *hF = fopen( "Newlogtst.txt", "w" );
if(hF == 0)
{
return 5;
}
fputs( (const char*)strtxt, hF );
fclose(hF);
return 1;
}
int tst()
{
return 25;
}
function tst works ok, function myfunc make empty file Newlogtst.txt and shows exception .
`
Exception thrown at 0x6113333A (cygwin1.dll) in CygwinDlltest.exe:
0xC0000005: Access violation reading location 0x004E0059.
If there is a handler for this exception, the program may be safely
continued.
`
in visual studio I am using this code
#include <windows.h>
typedef int (*PFN_HELLO)();
typedef void (*PFN_CYGWIN_DLL_INIT)();
int main()
{
PFN_HELLO func;
HMODULE hLib, h = LoadLibrary(TEXT("C:\\cygwin\\bin\\cygwin1.dll"));
PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT) GetProcAddress(h,"cygwin_dll_init");
init();
hLib = LoadLibrary (TEXT("C:\\Cygwin\\home\\azatyan\\TestDynamicLink\\mydll.dll"));
func = (PFN_HELLO) GetProcAddress (hLib, "myfunc");
return func();
}
please help what should I do to use library functions.
You don't check the returncode of GetProcAddress().
If you compile it in C++, the names are mangled differently, (which is why GetprocAddress() will return NULL btw.) because they are different compilers.
If you are just using basic functions like in your example, you should declare them as extern "C" so that they wont get mangled. Also make sure that the __declspec export statement are used correctly when compiling the DLL.
I have an exception is a dll i'm using when initializing a static local variable to a class instance.
The exception occurs when returning from the class constructor.
The exception I get in release is:
ConsoleApplication1.exe: 0xC0000005: Access violation reading location 0x00000000BA3529A2.
and in debug I get a debug assertion:
Debug Assertion Failed!
Program: E:\Sandbox\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe
File: f:\dd\vctools\crt\crtw32\misc\dbgheap.c
Line: 1516
Expression: _CrtIsValidHeapPointer(pUserData)
This is the function that fail (Part of the CImg library which is excellent!):
static const CImg<Tuchar>& jet_LUT256() {
static CImg<Tuchar> colormap; // <--- static local variable decleration
// exception here. after returnning from the CImg constructor :-(
cimg::mutex(8);
if (!colormap) {
colormap.assign(1,4,1,3,0);
colormap[2] = colormap[3] = colormap[5] = colormap[6] = colormap[8] = colormap[9] = 255;
colormap.resize(1,256,1,3,3);
}
cimg::mutex(8,0);
return colormap;
}
When the project was running as an exe everything worked fine.
Problem started when I made it a dll, and used it in another exe.
Solved.
Found out that the problem was that I used the /NOENTRY property (big NONO!)
(because when I converted it from exe to dll I had a link error with unresolved function mainCRTStartup)
removed the /NOENTRY from Properties->Linker->Advanced and error is gone.
I am trying to define a variable from an external library in C++, Visual Studio 2010. It only works when I put it outside of the main function.
This code crashes:
#include "StdAfx.h"
#include <ogdf\basic\Graph.h>
#include <ogdf\basic\graph_generators.h>
int main()
{
ogdf::Graph g;
ogdf::randomSimpleGraph(g, 10, 20);
return 0;
}
It gives me an unhandheld exception: Access violation.
However, if it is outside main function, it works without any problem:
#include "StdAfx.h"
#include <ogdf\basic\Graph.h>
#include <ogdf\basic\graph_generators.h>
ogdf::Graph g;
int main()
{
ogdf::randomSimpleGraph(g, 10, 20);
return 0;
}
Do you have any how do I fix that? I assume, that it is caused by some kind of linking problem.
EDIT: It looks like the problem is not the initialization of the variable. It throws an exception, when the application exits.
int main()
{
ogdf::Graph g; // No problem
ogdf::randomSimpleGraph(g, 10, 20); // No problem
int i; // No problem
std::cin>>i; // No problem
return 0; // Throws an exception after read i;
}
Call stack:
The output is:
First-chance exception at 0x0126788f in graphs.exe: 0xC0000005: Access violation writing location 0x00000000.
Unhandled exception at 0x0126788f in graphs.exe: 0xC0000005: Access violation writing location 0x00000000.
Works on my machineā¢.
Esoteric errors like that are often a result of binary incompability. Basically, because of different compiler/preprocessor options, effective headers that your code and the library "see" are different.
For instance, if you have a library with following header code:
class Foo
{
#ifdef FOO_DEBUG
int debug_variable;
#endif
int variable;
};
Library function:
void bar(Foo& foo)
{
std::cout << foo.variable;
}
And client code:
Foo foo;
foo.variable = 666;
bar(foo);
If FOO_DEBUG is not in sync amongst client and the library, this will possibly crash and burn -- variable will have different expected offset.
In your case, I suspect one of the following may be true:
You have built the ogdf with different compiler than your code
If not, you ogdf and your code have different build configurations (Release vs Debug)
Both are debug, but you have defined OGDF_DEBUG (as recommended here)
You have different "Struct Member Alignment" setting
I get an unhandled exception if I close my program using Poco mutexes.
I use a global
Poco::Mutex mymutex ;
in my cpp file, because I have a static class for logging (I also tried to declare it as a static member, but I got the same error).
The relevant part of my code (it's a static function):
void Log::log(std::string message)
{
try
{
Poco::Mutex::ScopedLock lock(mymutex);
std::ofstream f("log.txt", std::ios_base::app) ;
f << message << std::endl ;
f.close() ;
}
catch (...)
{
}
}
This part of the code works great in my program (there are no lines on each other like before using mutexes), but after I close my program, I get the following error message:
Unhandled exception at 0x77c3a710 in myprogram.exe: 0xC0000005:
Access violation writing location 0x00000014.
I also tried to use mymutex.lock() and mymutex.unlock() before and after writing to the file, but I got the same error.
And I also tried this code:
while(!mymutex.tryLock())
Poco::Thread::sleep(30);
but it resulted an infinite loop, the program has not stopped after closing its window.
I use Visual Studio 2010 and Poco 1.4.