As the title says, I am using a managed dll (myManaged.dll) in my c# project (myProject). But myManaged.dll makes use of an unmanaged (c++) dll (myUnmanaged.dll).
My question is: Do I need to explicitly load myUnmanaged.dll in myProject along with the method declaration?
And if yes, then should it be like this:
[dllImport "myUnmanaged.dll", EntryPoint = "myMethod"]
public extern IntPtr myMethod(int myParam);
Thanks
No you don't need, as long as you are not going to use myUnmanaged.dll directly in myProject
Related
I want to use a C++ library for my asp.net website. I don't know how to make a .dll of the library and make it work. I tried making a dll and import it to asp.net. Do I need a to do something in the c++ code for the dll to work?
Source code: http://warp.povusers.org/FunctionParser/fparser.html
You could use:
[DllImport("dllname.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern double FunctionParser();
I am using SWIG to generate a DLL that will expose C++ functionality to a C# project. At the moment I:
Define a SWIG interface file
%module example
%{
/* Includes the header in the wrapper code */
#include "../pointmatcher/PointMatcher.h"
%}
...
%include "../pointmatcher/PointMatcher.h"
Use SWIG to generate a .cxx wrapper
swig.exe -c++ -csharp -outdir csharp example.i
Compile the .cxx wrapper with MSBUILD via CMake
# create wrapper DLL
add_library(example SHARED ${WRAP_CSHARP_FILE})
target_link_libraries(example pointmatcher)
install(TARGETS example
ARCHIVE DESTINATION ${INSTALL_LIB_DIR}
LIBRARY DESTINATION ${INSTALL_LIB_DIR}
RUNTIME DESTINATION ${INSTALL_BIN_DIR})
I then have a DLL file (example.dll) which I can inspect via Dependency Walker, and confirm that methods are being exposed as follows:
However, when I try to add this MSVC DLL as a reference to a C# project I get the error "It is not a valid assembly or COM component".
Based on answers at How can I add a VC++ DLL as a reference in my C# Visual Studio project? I have confirmed that SWIG itself generates P/Invoke calls, and that tlbimp doesn't recognise the DLL either.
You don't add the C++ dll to your project in the same way you would a C# dll. Instead it is called through the PInvoke system.
SWIG will generate some C# code for you, the easiest way to access the dll is to include those files in your porject, which expose the dll functionality through some C# functions which you can call.
You can also use the dll through PInvoke yourself. You need to create a C# function that will act as a wrapper:
C++ Header:
#ifndef TESTLIB_H
#define TESTLIB_H
extern "C" {
int myfunc(int a);
}
#endif
C++ Code:
int myfunc(int a)
{
return a+1;
}
C# Code:
using System;
using System.Runtime.InteropServices;
class Libtest
{
[DllImport ("function")]
private static extern int myfunc(int a);
public static void Main()
{
int val = 1;
Console.WriteLine(myfunc(val));
}
}
Output:
2
Location of the DLL
The compiled C++ dll needs to either be copied into the C# project bin directory, or if the path is known it can be added to the DllImport call:
[DllImport("path/to/dll/function.dll")]
To achieve this with swig use the -dllimport flag:
swig -cpp -csharp ... -dllimport "/path/to/dll/function.dll" ...
If you want to set the path dynamically (to allow for loading 32-bit or 64-bit versions dynamically selected at runtime) you can use the kernel32 function SetDllDirectory which is also loaded using DllImport.
I am aware of this similar question, but it does not respond to my problem.
I have written two .dlls using Visual Studio 2010. One is in C++, and communicates with an SDK that was written in C++. The other is a C# wrapper for that C++ library, so that it can be used in C# contexts.
My plan was that this would let me use my code in Unity3D, but apparently that is not the case. It seems like Unity3D does not allow me to import .dlls as Assets if they are not a .NET assembly. So I can add my C# wrapper, but not the C++ dll.
This results in a DllNotFoundException whenever I try to access the C++ library. I have tried simply copying the C++ library into the Assets/Plugins folder, but that gives the same results.
Is there a way to do this properly? This is a very vital part of my project setup.
The problem is that the DLL is not being found when the p/invoke runtime code calls LoadLibrary(YourNativeDllName).
You could resolve this by making sure that your DLL is on the DLL search path at the point where the first p/invoke call to it is made. For example by calling SetDllDirectory.
The solution that I personally prefer is for your managed code to p/invoke a call to LoadLibrary passing the full absolute path to the native DLL. That way when the subsequent p/invoke induced call to LoadLibrary(YourNativeDllName) is make, your native DLL is already in the process and so will be used.
internal static class NativeMethods
{
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern IntPtr LoadLibrary(
string lpFileName
);
}
And then somewhere in your code:
private static IntPtr lib;
....
public static void LoadNativeDll(string FileName)
{
if (lib != IntPtr.Zero)
{
return;
}
lib = NativeMethods.LoadLibrary(FileName);
if (lib == IntPtr.Zero)
{
throw new Win32Exception();
}
}
Just make sure that you call LoadNativeDll passing the full path to the native library, before you call any of the p/invokes to that native library.
Note that the DllNotFoundException can be caused by building your Unity DLL in Debug instead of Release!
A simple oversight that can cause a headache.
This also happens when Unity can find your DLL, but is not able to find it's dependencies. Obvious fix is to place dependency DLLs into /Plugins as well, or link your dependencies statically.
Less obvious reason is when your DLL depends on Visual Studio runtime library dynamically, i.e. is built with Properties -> C/C++ -> Code Generation -> /MD option. Change it to /MT to link with runtime statically.
I've created a C# application. Within this application I would like to use/run a C++ API from another project(the API is written in macro coding). I tried import the dll of that C++ project and tried to call a functions which belongs to that API. The problem is that it throws "unable to find method" error.
How can I run a C++ project in a C# project?
You can't add a native DLL as a reference to a managed project. You have 3 main options:
Make the native functions available with p/invoke.
Expose the native code through COM.
Compile the native code as a managed C++ assembly.
For any serious amount of code, option 3 is the most productive and effective approach.
If by "running", you mean a separate process:
Use the class System.Diagnostics.Process available in .NET:
myProcess.StartInfo.FileName = "notepad.exe";
myProcess.StartInfo.CreateNoWindow = false;
myProcess.Start();
Else, if you mean using a dll developed in C++, you can use Platform Invoke Services:
using System;
using System.Runtime.InteropServices;
class PlatformInvokeTest
{
//First param is of course either in your PATH, or an absolute path:
[DllImport("msvcrt.dll", EntryPoint="puts", CallingConvention=CallingConvention.Cdecl)]
public static extern int PutString(string c);
[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
internal static extern int _flushall();
public static void Main()
{
PutString("Test");
_flushall();
}
}
I got a DLL that I want to add to my C# project and I have some problems. First, my DLL is coded in C++ and I got an interface of one function to export it.
extern "C" __declspec(dllexport) char* sniff()
{
return ps.Sniff();
}
I have an instance "ps" that initialise a socket when the DLL is attached. The point is that I need to have this instance initialise when I call my exported function. My problem is when I import it in my C# project, my DLL is detached for no apparent reason and I can no longer call my exported function.
I use this syntax in my C# projet :
[DllImport(#"C:\Documents and Settings\Pat\Bureau\sniffoporn\Release\sniff.dll", EntryPoint = "sniff", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr sniff();
Some important things that I tryed :
Import the DLL in the reference of the project : Can't because it's not a COM component.
Manually import the DLL using LoadLibrary, FreeLibrary and GetProcAddress : Same result
Call my exported function in loop : Same thing but the DLL is attached for a little longer before detaching.
I would want to know why my DLL is detaching and how can I keep it attached for the rest of the process life.
Thanks a lot
Maybe an exception occurs in your DLL itself. Making it detach in Visual Studio to prevent your application from crashing. After all C# is managed code.
Try your same procedures with a different (dummy) dll with very simple functionality. If it still occurs then something with your method is wrong, otherwise with the DLL you are attempting to use.