I getting bug: crash happened outside the Java Virtual Machine in native code. whenever i run with class file with native library and .net module file it works fine.
but when i try to run alone class file and native library it gets crash .please clarify my mistake i have done, please review my code.
for your reference with parameter
==========================================
public class Sum
{
public int add(int a, int b)
{
return a + b;
}
}
===========================================
save as Sum.cs and compile it to module
using cmd:
csc /t:module sum.cs
Create Java File to test
===========================================
public class test{
public native int add(int a,int b);
static {
System.loadLibrary("JSample");
}
public static void main (String[] args) {
System.out.println(new test().add(10,15));
}
}
==========================================
save it as test.java compile as
javac test.java
create native header file
javah -jni test
it will create test.h
create win32 project using visual studio (I used VS2010)
Choose project name as JSample
include header and C#.net module
write header for manged C++ conversion
==============================================
#using <mscorlib.dll>
#using "Sum.netmodule"
using namespace System;
public __gc class SumC
{
public:
Sum __gc *t;
SumC()
{
t = new Sum();
}
int callCSharpSum(int a,int b)
{
return t->add(a,b);
}
};
===========================================
save it as sum.h
create sum.cpp file
============================================
#include <jni.h>
#include "test.h"
#include "sum.h"
JNIEXPORT jint JNICALL Java_test_add
(JNIEnv *, jobject, jint a, jint b)
{
SumC* t = new SumC();
return t->callCSharpSum(a ,b );
}
=============================================
optimize compiler to build /clr:oldSyntax
Include Jdk/Include directory path
build the project.
we will Get JSample DLL
run the project
with C#.net module,Native DLL file and class file at the same folder.
java test
25
but whenever i run the code with dll file and class file alone.
it shows bug report The crash happened outside the Java Virtual Machine in native code.
please clarify how to port managed code C# into C++ (Win32 Un-Managed code). library file.
To use .NET assemblies from Java, I strongly suggest you look at IKVM, which is a Java VM that bridges to .NET Runtime.
I've used this back in (I think) 2004 for production software and it worked nicely. The project is actively maintained and recieves support for .NET 4 and Java 7 these days.
You have a choice of
running the Java code in IKVM so you can use .NET libraries
run a .NET program that loads java libraries (e.g. jars)
Both ways, there is a preprocessing step to translate the jars to DLLS or viceversa.
See http://ikvm.net
Related
I have x64 native C++ library that I have to pass to C# project.
I built C++/CLI wrapper, based on this tutorial, and everything was ok.
But, the project compiles only on x86 architecture.
When I tried adding that native C++ library to project, I received runetime error.
Project doesn't work on x64 architecture because wrapper for some reasons requires x86. And, on the other hand, it doesn't work on x86 because that library requires x64.
I have very little experience with C++/CLI, wrappers, and C# in general, and I don't have much idea how to go around this problem.
When tring to compile Solution, I receive runetime error
System.BadImageFormatException: Could not load file or assembly 'Wrapper, Version=1.0.7178.20781, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was ma
de to load a program with an incorrect format..
Link to error documentation
Here is my Wrapper
using namespace System;
namespace CLI {
template<class T>
public ref class Wrapper
{
protected:
T* m_Instance;
public:
Wrapper(T* instance)
:m_Instance(instance)
{
}
virtual ~Wrapper()
{
if (m_Instance != nullptr)
{
delete m_Instance;
}
}
!Wrapper()
{
if (m_Instance != nullptr)
{
delete m_Instance;
}
}
T* GetInstance()
{
return m_Instance;
}
};
}
...And here is a C++/CLI class that is using this wrapper
//**********************header file***********************
#include "Wrapper.h"
#include "../Core/Core.h"
using namespace System;
namespace CLI
{
public ref class Model : public Wrapper<Core::Impl>
{
public:
Model();
bool test();
};
//**********************Implementation******************************
#include "Model.h"
namespace CLI
{
Model::Model()
:Wrapper(new Core::Impl())
{
Console::WriteLine("Creating new Impl-wrapper object!!");
}
bool Model::test()
{
return m_Instance->test();
}
}
Its pretty much exacly the same as from the tutorial that I used.
I can not modify that native C++ library, so it has to work on x64 architecture.
Can you please explain to me, why wrapper doesn't want to compile on x64, but works perfectly on x86, and is there a way to go around this. Perfect answer would provide an example of C++/CLI Wrapper that is working on x64 architecture.
Thanks in advance
EDIT,
oh, and I forget to add properties of my project so.
OS is Win10 (x64); .NET target framework 4.5.1; Core project(the lowest layer project, not presented here) is built as static .lib, and Wrapper is a dynamic .dll.
VisualStudio 2017 v15.9.14
Double check your project setting, especially linker. Check Command line tab for linker. Recently I encountered wild X86 flag there in Additional options that gave me similar errors.
In advanced, check Target machine.
Try to enable verbose output for linker and compiler, and check for any occurrence of x86.
If all of that is ruled out, make sure that your lib was really compiled and is valid, eg. via dependency walker.
I've compiled a dll from a C++/CLI project in Visual Studio.
The code looks like:
#include "stdafx.h"
#include "api209.h"
using namespace System;
using namespace api209;
namespace CDK_net {
public ref class CDK_wrapper
{
public:
CDK_wrapper::CDK_wrapper(){};
public:
void init(){
//some magic
}
};
}
So this dll references a few other native C++ dlls and libraries, and does some stuff in the init() function.
If I create a C# project, reference this dll, the CDK_wrapper.init() works perfectly fine.
Now I want to reference this dll from a python script. So I have Python 2.7.15 and pythonnet to allow me to do this.
If I create a simple script:
import sys
import clr
dlldir = "C:\\dir\\of\\dll\\"
dllname = "CDK_net"
sys.path.append(dlldir)
clr.AddReference(dllname)
from CDK_net import CDK_wrapper
cdk = CDK_wrapper()
#works fine until here
cdk.init()
I get the following error when running it in Python:
Traceback (most recent call last):
File "test_script.py", line 33, in <module>
cdk.init()
System.Runtime.InteropServices.SEHException: External component has thrown an exception.
at api209.model.open(model* , SByte* , Repository* )
at CDK_net.CDK_wrapper.init() in d:\(...)cdk_net.h:line 21
So the error traces back to function in a C++ library which is referenced by my C++/CLI managed dll.
My question is; whatever is happening in the init() function in my dll, if it works when being called by a C# application, is there any reason why it shouldn't work when being called by python using pythonnet?
This question already has an answer here:
Using C# dll in C++ code
(1 answer)
Closed 7 years ago.
I have a dll file which is created in the c# language.And I wanted to use the functions which are written in c# language in that dll file from a c++ project.
I know it's possible to use c# dll with c# project. But no idea of what is the best way of doing c# dll in c++ project. I'm using visual studio 2013. All your guidance are highly appreciate.
I'll summarize the basic steps to take to expose a C# class to C++ through COM. Let's say you have the following C# class:
public class Number
{
public Number()
{
}
public int Value
{
get;
set;
}
}
First you need to create an interface for the class to implement. Only the methods and properties exposed through that interface are visible to COM (and therefore C++). Typically this interface has the same name as the class, but with an "I" prefix:
public interface INumber
{
int Value
{
get;
set;
}
}
Next you need to add the ComVisible and Guid attributes to both the interface and the class. It's also recommended to add [ClassInterface(ClassInterfaceType.None)] to the class:
[ComVisible(true)]
[Guid("71CACDF6-B6CD-4A46-B951-02E5C542852C")]
public interface INumber
{
...
[ComVisible(true)]
[Guid("B5809A32-A066-42E3-96D7-09FE622BC994")]
[ClassInterface(ClassInterfaceType.None)]
public class Number : INumber
{
...
(I got the GUIDs by using the GUID utility that comes with Visual Studio. You can find it at C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools)
That's it for the C# side. After you build the C# DLL, you need to register it with COM by using the Regasm.exe command-line utility. Start the command prompt and type the following commands:
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\vsvars32"
Regasm ExampleDLL.dll /codebase /tlb
(You may need to modify the first one if your VS installation path is different.)
Now you can use the DLL from C++ like this:
#include <iostream>
#import "ExampleDLL.tlb" // This is a file that should have been generated by Regasm.exe
using namespace std;
using namespace ExampleDLL;
int main()
{
CoInitialize(NULL);
INumberPtr pNumber;
pNumber.CreateInstace(__uuidof(Number));
pNumber->Value = 5;
cout << pNumber->Value;
return 0;
}
For more details, see Exposing .NET Framework Components to COM.
I want to develop a plugin for a program (EXE) to interop with an external C# module. The plugin is one of the three dlls needed: this dll (A) calls a wrapper dll (Native/Managed, in C++/Cli) (B) to interop with a C# dll (C).
A is supposed to be loaded by a calling program (EXE) when deployed.
In testing, a message from the C# dll is displayed, which tells me dll A is correctly loaded by a C++ tester and subsequently has made successful call to other dlls.
In deployment, dll A is loaded by EXE if it only displays a message. However, when lines of code to call dll B are added, EXE no longer recognizes dll A.
I have made sure that all files are in the right place. So I think the problem lies in the extra lines of interop code to call dll B. Any idea as to where I should look for problem?
Here is the exported function in dll A:
int WINAPI Init()
{
FILE * pConsole;
AllocConsole();
freopen_s(&pConsole, "CONOUT$", "wb", stdout);
printf("Started\n");
//These two line below call the wrapper dll B
// which serves as a middle man between dlls A and C
NativeExport_ClientWrapper* client = createMyClass();
if (client) client->Test();
return 1;
}
Here is the unmanaged side of the wrapper B:
//----------------------------------------------
//NativeExport_ClientWrapper.h
//----------------------------------------------
//#pragma once
#pragma once
#pragma unmanaged
#define THISDLL_EXPORTS
#ifdef THISDLL_EXPORTS
#define THISDLL_API __declspec(dllexport)
#else
#define THISDLL_API __declspec(dllimport)
#endif
class ILBridge_ClientWrapper;
class NativeExport_ClientWrapper {
private:
ILBridge_ClientWrapper* __bridge;
public:
NativeExport_ClientWrapper();
public:
~NativeExport_ClientWrapper();
public:
THISDLL_API void Test();
};
extern "C" THISDLL_API NativeExport_ClientWrapper* createMyClass();
And here is the managed side of the wrapper:
//----------------------------------------------
//ILBridge_ClientWrapper.h
//----------------------------------------------
#pragma once
#pragma managed
#include <vcclr.h>
class ILBridge_ClientWrapper {
private:
gcroot<Client^> __Impl;
public:
ILBridge_ClientWrapper() {
__Impl = gcnew Client;
}
void Test() {
__Impl->test();
}
};
After exhaustive search, I found nothing that helps to resolve this issue, including doing library load debugging.
My other related posting is here: Unexpected Stackoverflow exception using CLR in a dll
And finally, by doing several things, this exception is gone and everything works now:
1) In my CS project, I use the unmanagedexports package (use NuGet package manager to install it: Install-Package unmanagedexports) to export static methods using the __stdcall calling convention. In this project, you need to add these:
using System.Runtime.InteropServices;
using RGiesecke.DllExport;
2) add the path to the wrapper header files to the unmanaged C/C++ project's property page (C/C++->general->additional include directories)
3) put the managed and native wrapper into one project/dll (built with /clr option), separate them from the other two modules (one for the managed C# and one for the unmanaged C/C++)
4) optionally, I added a definition file for the unmanaged C/C++ functions
5) make sure all modules are built against the same framework and platform. In my case, I use framework 4.0 and x86 platform. In some case, you need to add an app.config file with the following:
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>"
6) set the path in the environment pointing to where the dlls are deployed
That's about it.
I have C++ DLL as below
#include "stdafx.h"
extern "C" __declspec(dllexport)double Add(double a, double b);
extern double Add(double a, double b)
{
return a + b;
}
n here m trying to link this DLL with my C# app
using System.Text;
using System.Runtime.InteropServices;
namespace test
{
class Program
{
[DllImport("DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern double Add(double a, double b);
static void Main(string[] args)
{
Console.WriteLine(Add(1.0, 3.0)); // error here
Console.ReadLine();
}
}
}
m getting error:
"Unable to load DLL 'DLL.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)"
please help me out ...how can i link c++ dll with c# ?
The calling convention determines how function parameters are placed on the stack prior to a function invocation, and how they are removed (caller vs. callee) when the function returns. You can find out much more about this in about a million StackOverflow questions, or goto here and read up a little.
Regarding placement of the DLL within reach of the C# (aka .NET) application you're writing, I'm afraid I cannot comment on that except to say general DLL's must be in your lib-search path (PATH in Windows) the current directory, or the kernel's home directory (generally c:\windows\system32. Do NOT copy files to system32, btw. just setup your application to "run from" the directory where your DLL is residing and you should be fine. There are exceptions to this, and configuration settings that can radically alter this, but were I you i'd stick with simple for now. Complex can always come later.
You will either need to plant the dll in the same location as the C# exe or pack the dll inside the exe. The first option is simple enough. For the second option, check out Embedding DLL's into .exe in in Visual C# 2010
you got this error because DLL.dll wasn't in your Debug/Release Folder,
as far as i know visual studio doesn't know how to copy those files to your output folder manualy.
add the dll file to your C# solution
and then on files properties set build action to content
and set copy to output directory to copy if newer this will automate the copying