I am trying to make a DLL in C# for use in a couple other languages. I found RGiesecke's DllExport but it doesn't seem to work. It builds just fine and makes a dll, but when I open it in Dependency Walker it doesn't show any functions, and my calling code can't find them either.
I created a new "Class Library" project (VS 2013) and then installed "Unmanaged Exports (DllExport for .Net)" from NuGet. Are there any project settings I need?
Here is my code.
using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;
namespace ToolServiceDLL
{
public class Class1
{
[DllExport("addUp", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
public static double addUp(double num1, double num2)
{
return num1 + num2;
}
[DllExport("get5", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
public static int get5()
{
return 5;
}
}
}
I found the problem. It has it in the RGiesecke Documentation, but I missed it. In the project settings->Build->Platform target: you can not have it set to "Any CPU". You must have it set to x64 or x86 depending on if you want to use it in a a 64 or 32 bit application.
I had a similar problem, but had already set the platform target to x64 and had the following error:
The name 'CallingConvention' does not exist in the current context
I found adding the using directive System.Runtime.InteropServices resolve the problem.
This is a good question and worked for me. Just took a bit more time than it should due to the Python side where I made a mistake. Here is the working code in Python3
import sys
import clr
sys.path.insert(0,'C:\\your_path\\Py2NetComm\\bin\\Debug')
clr.AddReference("Py2NetComm")
import ToolServiceDLL as p2n
ret = p2n.Class1.addUp(2,3)
print("addUp:", ret)
Related
I want to run C# dll with .net framework 4.7 in python app.
I use dllExport nuget for my method in dll because ctypes with this way access my method.
Sample:
using System.Runtime.InteropServices;
namespace MyNameSpace
{
public class MyClass
{
[DllExport("MyMethod", CallingConvention = CallingConvention.StdCall)]
public static int MyMethod(int a,int b)
{
return a + b;
}
}
}
In python:
def myFunction():
Dllpath = os.path.join("dll folder directory")
os.add_dll_directory(Dllpath + r"myDll.dll")
# WinDll used just windows os, in Linux is different
lib = WinDLL(Dllpath + r"myDll.dll")
lib.MyMethod(12,17)
it is work.
but when I use other library (dll) in my dll I get this Error:
[WinError -532462766] Windows Error 0xe0434352
I guess this error was for problem in dependency of my dll.
how to resolve this error?
you should put "DllExport" above all functions you call in all dependencies too.
I used the popular Robert Giesecke template for unmanaged exports in order to create a DLL for usage from native code.
Actually it should be really simple because one only has to adapt the given example function. Building works, but this command doesn't show me any function:
$ dumpbin.exe /exports <mydllname>.dll
My exported function looks like this:
using RGiesecke.DllExport;
namespace HelloWorld
{
internal static class UnmanagedExports
{
[DllExport("_adddays", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]
static double AddDays(double dateValue, int days)
{
return System.DateTime.FromOADate(dateValue).AddDays(days).ToOADate();
}
}
}
Does anyone have an idea what I am doing wrong? I'd be very happy about any help.
FYI: I'm using VS 2012, .NET-Framework 4.5, used class-library project template. I already tried changing the platform target to x86 (recommended in other posts) but didn't help.
SOLVED: Thanks to Casey Price for their answer. I then ran into 2 other errors: BadImageFormatException and FileNotFoundException, the former was solved by matching the platform target (x64 or x86) for each project and the latter was solved by setting the output directory of the C# project to the directory containing the dll file.
I'm working on a game 'engine' which currently has a working graphics subsystem that draws/textures movable models. I'm trying to write a C++/CLR wrapper so I can use the engine in a C# program (as a designer tool).
My wrapper project is a C++/CLR class library and contains the following 2 files (as well as resource.h/cpp and Stdafx.h/cpp)
// pEngineWrapper.h
#pragma once
#define null NULL
#include "..\pEngine\pEntry.h"
using namespace System;
namespace pEngineWrapper
{
public ref class EngineWrapper
{
public:
EngineWrapper();
~EngineWrapper();
bool Initialise();
private:
pEntry* engine;
};
}
and the .cpp file
// This is the main DLL file.
#include "stdafx.h"
#include "pEngineWrapper.h"
pEngineWrapper::EngineWrapper::EngineWrapper()
{
engine = null;
}
pEngineWrapper::EngineWrapper::~EngineWrapper()
{
delete engine;
engine = null;
}
bool pEngineWrapper::EngineWrapper::Initialise()
{
bool result;
engine = new pEntry;
result = engine->Initialise();
if( result == false )
{
return false;
}
return true;
}
When I go to build this project however I get 14 errors: LNK2028, LNK2019, and LNK2001 which points to some classes within the engine. I have included the errors in the file below.
https://www.dropbox.com/s/ewhaas8d1te7bh3/error.txt?dl=0
I also get a lot of warnings regarding XMFLOAT/XMMATRIX which you may notice.
In all of the engine classes I use the dllexport attribute
class __declspec(dllexport) pEntry
I feel like I'm missing the point and doing it all wrong seeing all of these errors but I haven't found any documents telling me anything considerably different than what I'm doing here
you have to add a reference to the static .lib files for the game engine you are using as well as it's dll's or load the dll's manually
to add the references to the .lib files right click your project->Properties->Linker->input add the lib file to the additional dependencies
See also: DLL References in Visual C++
Main goal: Create a wrapper for a C# library, which can be used in Python (2.6).
UPDATE: Now, I have updates to the method I am using, which is however not working well.
The code for the simple C# class library:
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace Test
{
[Guid("8F38030D-52FA-4816-B587-A925FDD33302")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface _TestClass
{
[DispId(1)]
string Eureka();
}
[Guid("BC3F6BB3-42C4-4F30-869A-92EA45BF68D2")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Test.TestClass")]
public class TestClass : _TestClass
{
public TestClass()
{
}
public string Eureka()
{
return "Hudson, we no longer have a problem!";
}
}
}
enter code here
In addition to this, I went into Project Properties and enabled the setting: Register for COM interop.
Also, in order to make the class library available to COM, I ticked Signing -> Sign the Assembly, and gave it a strong key.
Furthermore, whenever I compile, I unregister the old version with:
regasm -u Test /tlb:Test
And I register it with:
regasm Test.dll /tlb:Test
My problem is then, in the Python environment, I have the following main.py, which is not working:
import win32com.client
o = win32com.client.Dispatch("Test.TestClass")
The error is unforgiven.
thank you in advance!
A alternative would be if you you use Python for .NET. There seem to be alpha releases for Windows CPython 2.6 and 2.7 available. You could run simply:
import clr
clr.AddReference("Your.Assembly.Name")
import Test
test = Test.TestClass()
print test.Eureka()
I am new to .net .
I have a managed C++ library. It looks like this.
// header file
namespace cppnetdll
{
public __gc class Class1
{
public:
static int foo_int(void);
};
}
// source file
namespace cppnetdll
{
int Class1::foo_int(void)
{
return 123;
}
}
I can call this from a managed c++ program. When I try to call it from
a C# program, I get the compiler error: "The type or namespace name
'Class1' could not be found (are you missing a using directive or an
assembly reference?)" The error refers to the DllImport line below.
Here is the C# code
[code:1:a72c1df571]
namespace csuser
{
public class xxx
{
[DllImport("cppnetdll.dll")] extern
int Class1.foo_int();
private void yyy() { int i =
foo_int(); }
}
}[/code:1:a72c1df571]
I have tried various approaches but no success. What is the magic
syntax ?
It's funny that I can call unmanaged C++ functions from C# fairly
easily by declaring the functions as "C" and exporting from the DLL.
I expected calling managed code to be easier. Maybe it's so easy
that no one thought of documenting it !
You do not use a [DllImport] directive to call code that's written in managed C++. That is only intended for native DLLs that export their functions. Neither of which applies to yours, it isn't native and you don't export the function.
You built a managed assembly, you can treat it just like one you'd have written in C#. Project + Add Reference, Browse tab, navigate to the DLL. Or better yet, put both projects in one solution, use the Projects tab to select the reference.
Instead of using the [DllImport ...]
Try just adding a reference, here is a how to from MSDN:
http://msdn.microsoft.com/en-us/library/7314433t%28v=VS.90%29.aspx