How to call pure virtual functions in dll from exe application? - visual-c++

I have a dll which has an abstract class with all of its member functions are pure virtual functions. I am trying to write an application to call these functions. What are the steps I need to take to call these pure virtual functions?
This is a just a prototype
Header file with abstract class : interface.h [These are the exported functions]
class MathFuncExport {
public:
virtual int Add(int a, int b)=0;
MathFuncExport(){};
virtual ~MathFuncExport(){};
};
Header file in dll : MathFuncDll.h
#include "intf.h"
class MyMathFuncs : public MathFuncExport
{
public:
MyMathFuncs(){};
virtual ~MyMathFuncs(){};
virtual int Add(int a, int b);
};
Implementation : MyMathFunsDll.Cpp file
#include "MathFuncDll.h"
int MyMathFuncs::Add(int a, int b)
{
return a + b;
}
This created a dll but I am not able to call the functions in abstract class or I am missing some link here. Please help me in resolving this issue.
Thanks

You cannot call pure virtual. They are implemented to force function(s) implementation.
Since your base class is in the DLL you have to export class in order to use it for deriving other classes.
The easiest way to export class is to use implicit linking; this way you need a header for the class declaration and import library. For overllok of the different linkages check this link.
For a little demo create Win32 dll. Check MFC support if you need it and check the Export Symbols box.
This will create a dll with sample class and global variable export. Look at the header file where special macro is created, having different meaning for DLL (export) and executable linking with this dll (import).
Once you understand how to use implicit linking, you will be able to derive class from the base class in the dll as if you were using code in the executable module.

Related

How can I use the same namespace names in cpp-winrt idl file and a normal/standard cpp class?

The scenario is new and I believe it might be a bug in cpp-winrt module or the vc compiler.
The Problem
1. Create a "windows runtime component" using the cpp-winrt template for universal windows.
2. Note the namespace name defined in the idl file. By default the idl file is named as class.idl.
3. Add a "new standard cpp class" to the project using the class wizard.
4. Put the new class under the same namespace name as defined in the idl file.
5. Build the project.
a. The build should succeed.
6. Use the standard cpp class in the runtime implementation class.
7. Now try to build the project again.
a. The build will fail this time.
The Reason
1. cppwinrt.exe generates source files from the idl file.
2. The runtime implementation class namespace is prefixed by "winrt".
3. The standard cpp class is not prefixed by the namespace "winrt".
4. The vc compiler expects the standard cpp class namespace to start from "winrt"
5. Otherwise the name resolution fails even if you try to use the fully qualified namespace name.
Example runtime idl file
namespace NMLevel1.NMLevel2
{
[default_interface]
runtimeclass Class
{
Class();
void RuntimeMethod1();
Int32 RuntimeMethod2(Int32 arg1);
String RuntimeMethod3(String arg1);
Int32 MyProperty;
}
}
Example standard cpp file
#pragma once
#include <string>
using namespace std;
namespace NMLevel1::NMLevel2
{
class StdCPPClass
{
public:
StdCPPClass();
virtual ~StdCPPClass();
void method1();
int method2(int arg1);
wstring method3(wstring arg1);
};
}
Example runtime class implementation
#include "pch.h"
#include "Class.h"
#include "NMLevel1.NMLevel2.Class.g.cpp"
#include "StdCPPClass.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace winrt::NMLevel1::NMLevel2::implementation
{
void Class::RuntimeMethod1()
{
NMLevel1::NMLevel2::StdCPPClass stdcls;
Uri uri(L"http://aka.ms/cppwinrt");
//printf("Hello, %ls!\n", uri.AbsoluteUri().c_str());
printf("RuntimeMethod1(): Hello, %ls!\n", stdcls.method3(uri.AbsoluteUri().c_str()).c_str());
}
}
NMLevel1::NMLevel2::StdCPPClass stdcls; is not allowed without prefixing the namespace with winrt.
Is this a bug or a design limitation that cannot be overcome?
or How can I use the same namespace 'NMLevel1::NMLevel2' in idl and cpp files?
Name lookup in C++ is fairly involved, especially when namespaces get essentially merged through using declarations. To help the compiler identify the name you want, you'll have to be explicit, and use a fully qualified name (as opposed to a qualified name, as in the sample).
You'll have to change
void Class::RuntimeMethod1()
{
NMLevel1::NMLevel2::StdCPPClass stdcls;
// ...
}
to
void Class::RuntimeMethod1()
{
::NMLevel1::NMLevel2::StdCPPClass stdcls;
// ...
}
Note the leading :: scope resolution, which limits lookup to the global scope (or namespaces introduced into the global namespace through a using declaration). You'll find additional information here: Qualified name lookup.

passing object from c# to c++

I've been working on a prototype code application that runs in C# and uses classes and functions from older C++ code (in the form of an imported DLL). The code requirement is to pass in a class object to the unmanaged C++ DLL (from C#) and have it be stored/modified for retrieval later by the C# application. Here's the code I have so far...
Simple C++ DLL Class:
EXPORT_DLL int init(MyInitParams *initparams);
C++ DLL Functions:
struct MyInitParams {
public:
int _np;
int _nm;
int type;
double *CV_Weight;}
in c# DLL
[DllImport("NEWUSEMPC", CallingConvention = CallingConvention.Cdecl, EntryPoint = "init")]
public static extern int init(InitParams parameters);
in c# class
class InitParams
{
public int _np;
public int _nm;
public int type;
public double[] CV_Weight;}
If you own the code of the c++ dll it would be a lot more convenient for you to include it in your solution, and create an interop between c# and c++ using managed c++ as a translation layer. Be aware, that the managed c++ layer should only do the translation of data and invoke the native method, and literally nothing else, because managed c++ is designed only as a bridge between the native and managed world.
You can also use mixed debugger to check out what is happening in both managed and unmanaged code in debug to take a look on the variables, so that you can see what's missing.
I personally would discourage the use of platform invoke instead of an interop class, because the latter is a lot cleaner and is easier to maintain later on.

C++/CLI Interface is not visible from my C# Class

I have an interface in C++/CLI I need to implement in C#, but I it is not visible. However I have other classes (abstract and concrete that I can inherit from).
My C++/CLI Interface:
namespace MyNamespace { namespace MySubnamespace {
public interface class ITestInterface
{
public:
property bool FirstProperty
{
bool get();
}
property bool SecondProperty
{
bool get();
}
};
}}
I have a Test project where I use all the functionality in my Managed Library, but the Interface never becomes visible.
How I try to use it in my C# Test project: (I tried using it from a Class Library Project also, and it doesn't work either).
public class Test: MyNamespace.MySubnamespace.ITestInterface
{
}
I get "Cannot resolve symbol 'ITestInterface'"
What am I missing?
Update
I kept trying different things following the comments to my question, and I found that if I include my .h file in some other .h file of my C++/CLI project, the class becomes visible.
Basically I just do:
#include "ITestInterface.h"
In one of my other .h files of the C++/CLI project and the Class becomes visible to the c# project.
Is there a way I could avoid doing that?
C++/CLI is similar to C++ in that only .cpp files are compiled directly. Header files are only compiled when included. This is why adding an #include for your interface header works.
There are several ways to make sure your code is included for a C++/CLI class:
Have both a .h and .cpp file (even if the .cpp file only includes the .h file it corresponds to)
Have only include files and then include all of the headers in one .cpp file (which may be empty other than the includes)
Have only .cpp files (which is fine if the other code does not reference this code)

Export native type from C++/CLI project

How do I export the methods of a native class defined in a C++/CLI project? Here's what I have:
The .h file:
#pragma once
#ifdef COMPILE_PRODUCER_LIB
#define PRODUCER_LIB_EXPORT __declspec(dllexport)
#else
#define PRODUCER_LIB_EXPORT __declspec(dllimport)
#endif
public class PRODUCER_LIB_EXPORT MySecondNativeClass {
public:
MySecondNativeClass(int val);
int getValue() const;
private:
int m_value;
};
The .cpp file:
#include "stdafx.h"
#include "MySecondNativeClass.h"
MySecondNativeClass::MySecondNativeClass(int val) {
this->m_value = val;
}
int MySecondNativeClass::getValue() const {
return this->m_value;
}
Using this class in the same project works fine, but using it in another (C++/CLI) project gives me "unresolved external symbol" linker errors. (COMPILE_PRODUCER_LIB is a preprocessor definition defined only in the project that contains the class.)
I've created a small solution (for Visual Studio 2010) that shows the problem (download at the end of this page). There, the native class MySecondNativeClass is defined in the project "ManagedProviderLib" and is being used in "ExternalTestClass.cpp" (in project "ManagedExternalLib").
Your DLL project creates a .lib file in the build directory, the DLL's import library. You need to specify that .lib file in the other project, Linker + Input, Additional Dependencies setting.
Note that Add Reference cannot work, the assembly metadata only contains definitions for managed classes. Your class is native C++, not managed. Also make sure that your .cpp file is compiled without /clr in effect. The C++/CLI compiler will happily translate native C++ classes to IL but that is not very efficient. You can control this within the source code file with #pragma managed.

call unmanaged C++ code from C# using pinvoke

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

Resources