I have created a Qt/C++ .dll for use in a C#/WPF project.
The Qt section code is as below:
cpluspart_global.h:
#ifndef CPLUSPART_GLOBAL_H
#define CPLUSPART_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(CPLUSPART_LIBRARY)
# define CPLUSPARTSHARED_EXPORT Q_DECL_EXPORT
#else
# define CPLUSPARTSHARED_EXPORT Q_DECL_IMPORT
#endif
extern "C" __declspec(dllexport) void ShowSampleUI();
extern "C" __declspec(dllexport) int Sum(int a, int b);
#endif // CPLUSPART_GLOBAL_H
cpluspart.cpp:
#include "cpluspart.h"
CPlusPart::CPlusPart()
{
}
extern "C" void ShowSampleUI()
{
BenQ *sampleUI = new BenQ();
sampleUI->show();
}
extern "C" int Sum(int a, int b)
{
return a + b;
}
BenQ is an empty QDialog that is just used for tests.
Here is the implementation in C#:
[DllImport("CPlusPart.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void ShowSampleUI();
[DllImport("CPlusPart.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Sum(int a, int b);
The "Sum" method works properly. However, when I want to call "ShowSampleUI", I receive the following error:
Unhandled exception at 0x00007FFCD125286E (ucrtbase.dll) in CPlusInWPF.exe: Fatal program exit requested.
I would appreciate it if you could kindly help me with this issue.
Related
My C++ DLL name is MyDLL.dll, which is communicating with TestDLL.dll
Now, I want to call functions from MyDLL.dll in my C# project
Visualization
----------- communicates ------------- communicates ---------------
- C# Code - --------------> - MyDLL.dll - --------------> - TestDLL.dll -
----------- ------------- ---------------
MyDLL.dll is written in C++
TestDLL.dll is written in C
Here is the Code
MyDLL.h
#define MyDLL_API __declspec(dllexport)
extern "C" {
MyDLL_API int sum(int a, int b);
MyDLL_API int do();
}
MyDLL.cpp
#include "MyDLL.h"
#include <Windows.h>
extern "C" {
typedef int (CALLBACK* MYFUNC1)(int, int);
typedef short* (CALLBACK* MYFUNC2)(const char*);
int MyDLL_API sum(int a, int b) // This function works fine
{
return a + b;
}
int MyDLL_API do()
{
int t = -1;
HINSTANCE test_dll;
MYFUNC1 myFunc1;
MYFUNC2 myFunc1;
test_dll = LoadLibraryA("c:\\TestDLL.dll");
if (!test_dll) {
t=0;
}
myFunc1 = (MYFUNC1)GetProcAddress(test_dll, "TestFunc");
if (!myFunc1) {
t=1;
}
myFunc2 = (MYFUNC2)GetProcAddress(test_dll, "AuthFunc");
if (!myFunc2) {
t=2;
}
// If I put 'return t' here, it works fine!
(*myFunc2)("Hello World"); // <-- This line causing the error
return t;
}
}
C# Main Program
class Program
{
public class MyClass
{
[DllImport(#"c:\MyDLL.dll", EntryPoint = "sum")]
public static extern int Sum(int a, int b);
[DllImport(#"c:\MyDLL.dll", EntryPoint = "do")]
public static extern int Do();
}
static void Main(string[] args)
{
int summation = MyClass.Sum(30, 20); // This runs fine.
Console.WriteLine("Sum is: " + summation);
int resultCode = MyClass.Do(); // This causing the ERROR.
Console.WriteLine("Result code is: " + resultCode);
Console.ReadLine();
}
}
Exception Hint
System.AccessViolationException: 'Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.'
I wrote a C++ dll which I want to use in Unity3D. I put it into Assets/Plugins and wrote a C# script which should access a function of it but I get this error:
EntryPointNotFoundException: Multiply
test.Start () (at Assets/Scripts/test.cs:11)
Manager.h:
extern "C"
{
class Manager
{
public:
__declspec(dllexport) float Multiply(float a, float b);
};
}
Manager.cpp:
#include "Manager.h"
extern "C"
{
float Manager::Multiply(float a, float b)
{
return a * b;
}
}
C# script:
[DllImport("Manager", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
private static extern float Multiply(float a, float b);
void Start()
{
Debug.Log(Multiply(10, 2));
}
Edit: This doesn't work during I'm using a class. To use a class you have to do it like this
Suppose I want to call c++ functions from a c# code, I am having the following problem:
Case 1:
class abc
{
private :
int a ;
public :
int getValue()
{
return 100;
}
};
int GetCounter()
{
abc* p = new abc();
int i = p->getValue();
return i;
}
This case when calling the function from C# throws me a DLL not found exception.
Case 2:
int GetCounter()
{
int i = 333;
return i;
}
The case when calling the function from C# works just fine.
Any ideas why? How can I fix it?
use this sample Line of code in CPP Project (MathFuncsDll.h)
extern "C" __declspec(dllexport) double Add(double a, double b);
extern "C" __declspec(dllexport) double Sub(double a, double b);
extern "C" __declspec(dllexport) double Mul(double a, double b);
extern "C" __declspec(dllexport) double Div(double a, double b);
in C# Code use like this
[DllImport("MathFuncs.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Double Add(Double a, Double b);
[DllImport("MathFuncs.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Double Mul(Double a, Double b);
[DllImport("MathFuncs.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern Double Sub(Double a, Double b);
[DllImport("MathFuncs.dll",CallingConvention = CallingConvention.Cdecl)]
public static extern Double Div(Double a, Double b);
[DllImport("MathFuncs.dll",CallingConvention = CallingConvention.Cdecl)]
public static extern Double Bat(Double a, Double b);
I'm trying to learn how to use DLL's in C#. I have a very simple DLL just to test the basics.
// MainForm.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace DLL_Test
{
public partial class Form1 : Form
{
[DllImport("TestDLL.dll",
EntryPoint="?Add##YGHHH#Z",
ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int Add(int a, int b);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int num;
try
{
num = Add(2, 3);
richTextBox1.AppendText(num.ToString() + "\n");
}
catch (DllNotFoundException ex)
{
MessageBox.Show(ex.ToString());
}
catch (EntryPointNotFoundException ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
And the DLL code:
// TestDLL.cpp
__declspec(dllexport) int __stdcall Add(int a, int b) {
return(a + b);
}
dumpbin returns the following:
ordinal hint RVA name
1 0 00011005 ?Add##YGHHH#Z = #ILT+0(?Add##YGHHH#Z)
This (and other attempts listed below) have all returned the same exception:
System.EntryPointException: Unable to find entry point named "..."
So I am at a loss for how to solve this. Perhaps I do not understand how DllMain functions as the C# entry point for a DLL. TestDLL.dll works when I test it in a C++ application.
After searching for help, I've attempted the following changes:
// TestDLL.cpp
extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) {
return(a + b);
}
Which results in this from dumpbin
ordinal hint RVA name
1 0 00011005 _Add#8 = #ILT+135(_Add#8)
Thus, I changed my C# code:
// MainForm.cs
...
[DllImport("TestDLL.dll",
EntryPoint="_Add",
ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern int Add(int a, int b);
...
I've also tried __cdecl:
// TestDLL.cpp
extern "C" __declspec(dllexport) int __cdecl Add(int a, int b) {
return(a + b);
}
.
// MainForm.cs
...
[DllImport("TestDLL.dll",
EntryPoint="_Add",
ExactSpelling = true,
CallingConvention = CallingConvention.Cdecl)]
public static extern int Add(int a, int b);
...
Perhaps I'm misunderstanding the calling conventions. Any help would be very appreciated. Thank you.
use
extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) { ... }
and
[DllImport("TestDLL.dll", CallingConvention = CallingConvention.Stdcall)]
public static extern int Add(int a, int b);
extern "C" will prevent name mangling with params and return type such as ?Add##YGHHH#Z.
__stdcall will prepend an _ and add #8 : _Add#8 (where 8 is the total size of arguments). Note that it also affects the way parameters are pushed on the stack.
In your DLLImport statement, since you specify CallingConvention.StdCall, you don't need to specify the name mangling. Just give the regular name (Add) and .NET will take care of name mangling (_Add#8).
Note that you must specify the CallingConvention or .NET wouldn't emit the correct code to push arguments on the stack
The following should work.
Unmanged:
extern "C" __declspec(dllexport) int Add(int a, int b)
{
return(a + b);
}
Managed:
class Program
{
[DllImport("TestDLL.dll")]
public static extern int Add(int a, int b);
static void Main()
{
Console.WriteLine(Add(1, 2));
}
}
For future reference: I had a similar problem, solved creating an EMPTY C++ dll project. Probably the standard Visual Studio template causes some trouble.
Refer to this link: http://www.codeproject.com/Articles/9826/How-to-create-a-DLL-library-in-C-and-then-use-it-w
I have simple C++ dll function:
__declspec(dllexport) int tst1(int a);
int tst1(int a)
{
return a + 1;
}
I have C# application that calls it:
[DllImport("Project1.dll")]
public static extern int tst1(int i);
static void Main(string[] args)
{
Console.WriteLine( tst1(1) );
Console.ReadLine();
}
}
Got EntryPointNotFoundException error:
What I do wrong?
The name is getting mangled by C++ decoration. Add extern "C" to prevent the mangling of the name:
extern "C" __declspec(dllexport) int tst1(int a);