Last 10 years I was only using C#/Java so sorry about my simple questions about c++.
Now I've to add one c++ project to my solution. I do not need to be it standalone application, I need it to do some work and to transfer result to my another c# project. So I've created "Visual C++ / CLR / Class Library".
By default such project doesn't contain too much code. Just this:
// CliProject.h file
#pragma once
using namespace System;
namespace CliProject {
public ref class Class1
{
// TODO: Add your methods for this class here.
};
}
// CliProject.cpp file
#include "stdafx.h"
#include "CliProject.h"
Now for debugging I want to add "main" method so I can launch my library as standalone application. How to do that? Should I create one another class or I should use existent classes?
Create a 'CLR Console Application' project with a reference to your library. Or even better, for debugging, use a unit test framework.
Related
I am writing an example android app to demonstrate the use of our (university research) C/C++ library.
I know that, using jni, we can call C functions from java.
However, I have not found a step by step set of instructions for how to do this within Android Studio Artic Fox.
I have seen the need to write jni compatible C wrapper functions, but have not found how to do this (correctly formed function signatures) or where to put them.
In addition, what do I need to change in the project setup to correctly build the project (using gradle) ?
Note that I have to use directly the pre-built .so file and the public header file which defines the set of public C functions for the library.
There are plenty of examples which give partial outdated information, but still nothing comprehensive - or have I missed something ?
I put together a quick guide below, but I want to clarify how it all fits together first.
In an Android application, you can bind native methods to specially-named functions that are loaded from a native library.
These specially-named functions receive pointers to a JNIEnv struct to interact with the embedding Java application.
The native library is typically built using CMake. Any external dependencies (such as your prebuilt library) need to be made visible to CMake in its CMakeLists.txt. The weapon of choice here are IMPORTED libraries, which are exactly what you think they are.
the steps
First, create an Android project with Kotlin as language.
Right click the app at the top of the tree and select "Add C++ to module" to generate the necessary build stuff.
Change your MainActivity.kt file to be:
class MainActivity : AppCompatActivity() {
external fun doit();
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val nativeThread = Thread {
doit()
}
nativeThread.start()
}
}
You will get a build error stating "cannot resolve corresponding JNI function". If you select the quick fix for that, Android Studio will generate a .cpp file with the appropriate JNI wrapper code inside it.
The generated function will look like:
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_doit(JNIEnv *env, jobject thiz) {
// TODO: implement doit()
}
and above that will be instructions on how to load the native library from Kotlin. Copy that code to your MainActivity.kt.
Edit that .cpp file to do whatever you need to do with your native library (eg #include some files and call some functions).
Finally, edit app/src/main/cpp/CMakeLists.txt to point to your headers and precompiled library.
We've created our own implementation of IXMLHttpRequest in a COM server (.exe) like so:
interface IMyXMLHttpRequest : IXMLHttpRequest {
...
};
coclass MyXMLHttpRequest {
[default] interface IMyXMLHttpRequest;
};
The problem is that when the build tries to register the COM server, we get the error "Error accessing the OLE registry". I debugged the registration code and it is failing in RegisterTypeLib. It looks like it is trying to pull in some of the type information relating to IXMLHttpRequest and (guessing here) can't change some registry keys related to that interface.
Is it just plain wrong to derive from IXMLHttpRequest? Should we be deriving from IDispatch instead and making our class use a dual interface? Or is it possible to derive from IXMLHttpRequest and we're just doing it wrong?
Update: I've uploaded a reproducible test case. I simply generated an ATL COM server using the Visual Studio wizard, and then I created a new interface derived from IXMLHttpRequest and a coclass that implements it. The registration fails as I described. If I change the interface to derive from IDispatch then it works fine. 100% reproducible on Windows 7 using Visual Studio 2010, running with elevated privileges.
error MSB3073: :VCEnd" exited with code -2147319780.
Just for the record, the error is 0x8002801C TYPE_E_REGISTRYACCESS "Error accessing the OLE registry."
As you already identified, the problem is around inheriting from IXMLHttpRequest interface which is defined outside of the type library. Extending an interface through inheritance is basically not a good idea in first place. Yes it is possible and it makes sense, however as soon as you approach putting this into a type library and having external references, you might be starting hitting weird issues.
As soon as you referenced IXMLHttpRequest, MIDL compiler is trying to put it into your type library as well. You can witness this by looking into intermediate build files:
It is not what you wanted, is it? You just wanted to reference it because it is already defined and hosted by another type library in msxml6.dll file in system32 (syswow64) directory.
The main question is why you want to inherit from IXMLHTTPRequest. Why you think a "normal" separate new IDispatch-derived interface is not good enough here? You can still implement IXMLHTTPRequest on this COM class as well. And you would not get into this trouble in first place then.
Anyway, the building problem is that on IDL the compiler sees definition of IXMLHTTPRequest coming from Windows SDK file directly.
You want to change your IDL file as follows:
import "oaidl.idl";
//import "ocidl.idl"; // <<--- Make direct IXMLHTTPRequest definition invisible
[
uuid(7397D60F-A428-42C5-B698-9FA850638074),
version(1.0),
]
library COMServerTestLib
{
importlib("stdole2.tlb");
importlib("msxml6.dll"); // <<--- Reference MSXML type library to import the right interface
In your C++ file you want to make the interface visible for C++ code:
#include "stdafx.h"
#include "resource.h"
#include <msxml6.h> // <<--- Re-add IXMLHTTPRequest definition for C++ code
#include "COMServerTest_i.h"
Your project is buildable again from here.
I have a unmanaged C++ dll for which I do not have access to code but have all methods declarations for.
Lets for simplicity say that .h looks like this:
#include <iostream>
#ifndef NUMERIC_LIBRARY
#define NUMERIC_LIBRARY
class Numeric
{
public:
Numeric();
int Add(int a, int b);
~Numeric();
};
#endif
and method implementation in .cpp file
int Numeric::Add(int a, int b)
{
return (a + b);
}
I simply want to call the add function from C++ in my C# code:
namespace UnmanagedTester
{
class Program
{
[DllImport(#"C:\CPP and CSharp Project\UnmanagedNumeric\Debug\numeric.dll", EntryPoint = "Add")]
public static extern int Add(int a, int b);
static void Main(string[] args)
{
int sum = Add(2, 3);
Console.WriteLine(sum);
}
}
}
After trying to execute I have the following error:
Unable to find an entry point named 'Add' in DLL 'C:\CPP and CSharp Project\UnmanagedNumeric\Debug\numeric.dll'.
I CAN NOT change C++ code. Have no idea what is going wrong.
Appreciate your help.
Using PInvoke you can only call global functions exported from Dll. To use exported C++ classes, you need to write C++/CLI wrapper. This is C++/CLI Class Library project, which exposes pure .NET interface, internally it is linked to unmanaged C++ Dll, instantiates a class from this Dll and calls its methods.
Edit: you can start from this: http://www.codeproject.com/KB/mcpp/quickcppcli.aspx#A8
If you need to create a wrapper, take a look at swig.org. It will generate one for most high level language like C#.
I just came across this program a few minutes ago while working the same problem that you are.
To use a class from native C++ from C# you need a C++/CLi wrapper in between, as mentioned by by previous answers. To actually do that, it is not very straight forward. Here is I link that tell you how to do it at a high level: C++/CLI wrapper for native C++ to use as reference in C#.
If you are quite new to this (like me), you might stumble on 1) -- the linking part. To solve that, you can see how I did here (see my question portion): Link error linking from managed to unmanaged C++ despite linking to .lib file with exported symbols
I have a MonoTouch app that dynamically instantiates a class (using Type.GetType()) at runtime. The class is in an assembly that is not referenced anywhere else in the app, so the MonoTouch static compiler thinks that the assembly isn't used and ignores the assembly when it compiles the app. If I add a reference to the class in the app, then the compiler includes the assembly and the call to Type.GetType() works fine:
MyAssembly a;
I would prefer to just tell the compiler to always include all the assemblies listed in the project's "References" when it compiles the app. Is this possible?
Thanks,
-Tom B.
You will have to change your project's Linker behavior from "Link all assemblies" to "Link SDK assemblies only".
The other solution, if you have the project code that assembly was created with, is to mark the class you want to use with the PreserveAttribute.
Were you able to figure this out yet? If not, I had a similar problem: Is there a way to force MonoDevelop to build/load an assembly?
As I understand it, that's just how the C# compiler works. I was able to get around this by adding a custom pre-build step that scripts a class into the referencing assembly that includes dummy references to the unreferenced assemblies, like so:
using System;
namespace MyNamespace
{
public static class Referencer
{
Type t;
//These lines are scripted one per class in the unreferenced assemblies
//You should only need one per assembly, but I don't think more hurts.
t = typeof(Namespace1.Class1);
t = typeof(Namespace2.Class2);
...
t = typeof(NamespaceN.ClassN);
}
}
So I just began to try my hand at emulation after years of putting it off and not knowing where to start and I have managed to successfully write my first emulator! Now I am organizing my code in so that I can reuse the code to emulate other systems. I've been toying with the idea of having a shared frontend "platform handler" of sorts that I will compile as my executable whereas I will compile my emulated system code into dlls that the platform handler will use to identify what is available and instantiate from. This would allow me to separate my code into different projects and to leave the option open of using a bulkier front-end with more features or a streamlined "game only" and to share the same dlls between them rather than make two different solutions.
I know how to compile dlls vs executables but I don't know how to link the executable to the custom dll in such a way that I can instantiate a class from it. I'm not even sure what I'm trying to do is technically possible. Do the dll classes need to be static? I've never coded anything like this before or even done much with custom dlls so any help or ideas would be appreciated. I'm using Visual C++ 2010 by the way. Thanks in advance for any advice anyone may have.
You don't really have to do much different. Just export your classes from the dll like you do for functions. In your app, include the header and link to the generated lib like you usually do. See this page: http://msdn.microsoft.com/en-us/library/81h27t8c%28v=vs.80%29.aspx
Example.h
#ifdef DLL_EXPORT
#define EXPORT_API __declspec(dllexport)
#else
#define EXPORT_API __declspec(dllimport)
#endif
class EXPORT_API Example
{
public:
Example();
~Example();
int SomeMethod();
};
int EXPORT_API ExampleFuncion();
Example.cpp
#include "Example.h"
Example::Example()
{
// construct stuff
}
Example::~Example()
{
// destruct stuff
}
int Example::SomeMethod()
{
// do stuff
return 0;
}
int EXPORT_API ExampleFunction()
{
return 0;
}
In your dll project, define DLL_EXPORT and build. You will get a .lib and .dll output. In your main project where you will be using the dll you do not have to do anything except include the header and link against the .lib. Do not define the DLL_EXPORT symbol in your main project and be sure the .dll is somewhere your application can find it.
If you really want to get clever, this problem is screaming for the factory design pattern. If you design your interface well enough, you can have your dlls register their implementation with your application when they are loaded. You can extend forever without even rebuilding your main executable.