F# consuming unmanaged dll functions - c#

I have a project written in F# and I have to use an unmanaged DLL for part of it. I'm very new to .Net programing, so this is another level of complexity added on top of everything else.
In the unmanaged DLL's documentation they provide samples of how to consume the functions from C#, like so:
using System;
using System.Runtime.InteropServices;
[DllImport("foo.dll")] public static extern Int32 foo_init(
[MarshalAs(UnmanagedType.AnsiBStr), In()] ref string FOOarg_Handle,
[MarshalAs(UnmanagedType.AnsiBStr), In()] ref string FOOarg_User,
[MarshalAs(UnmanagedType.AnsiBStr), Out()] out string FOOarg_DataOut,
[MarshalAs(UnmanagedType.AnsiBStr), Out()] out string FOOarg_ErrOut);
This is pretty ugly in and of itself, but I have no clue how to do this from F#. Wouldn't it be a good idea to just create a C# class, put all the function definitions that wrap the external DLL's functions in there, and call those from F#, instead of calling the unmanaged functions directly from F#?
How else would one go about this? Thanks in advance!

There doesn't appear to be a description of the syntax for extern function declarations either on MSDN or in the spec. But, as far as I can tell, it mirrors the C declarations verbatim, as you can see from these (rather old) examples.
I left feedback on the MSDN page for External Functions suggesting it include explanation and examples of the syntax.

Related

Passing Structure to C#

I am writing code to parse a complicated string in C++ and create a tree from it. I would like to use C# in Visual Studio 2017 to call a native c++ method that returns a vector of nodes.
A Node looks like:
class node
{
public:
std::vector<node> subnodes;
std::string name;
};
and the c++ function might look like:
class noderizer
{
public:
node getNodes(std::string str);
};
what is the most efficient (coding time with secondary consideration for speed) way to call the noderizer::getNodes(...) member and create a equivalent class for c#?
I am assuming that the best route is to create a duplicate class definition in c# and then copy marshal the native std::strings into managed Strings"
public class node
{
public string name = string.Empty;
List<node> integers = new List<node>();
}
It's not clear if this article contains the latest information for c++ interop, but a related article on wrapping c++ native classes for use in c# indicates that I could most likely just wrap noderizer native c++ as noderizer * m_Impl; and then call the getNodes member and copy over each parameter. Is this the correct methodology?
You could use pInvoke as per your first referenced article, but the objects you are returning seem quite complicated. I think you will have a heck of a time with data marshalling if you're not already well versed (and even then). pInvoke is great for simple calls to C libraries where data marshalling is basic, but it gets very complicated very fast. This is not good for your situation.
The second article is closer to where you want to look. That being said, you have to consider whether you want to be wrapping a managed class or just calling a function that takes a string and returns your tree in managed format (i.e. it makes a copy rather than wrap unmanaged data). By your post it seems like you just need the latter.
Your best option is to use C++/CLI. Check out this tutorial. I am confident that taking this approach will make light work of your task. I won't attempt to explain the subject as the article above does a very good job. In essence, you will be able write functions with both managed and unmanaged data types, where all the data marshalling is built into the environment. A simple cast will marshal the data for you behind the scenes. As a big bonus, debugging is great as you can step from C# to C++/CLI to C++ code and back.
In the article above, the author does describe how to wrap an unmanaged class, which you can well do, but your problem will still be with data conversion.
I would approach your problem in 4 steps:
Write a static function getNodes() in C++/CLI that you can call from C# as any regular static method, passing a string as an argument. The article above will help you with that. Also See Here when creating the C++/CLI project.
getNodes() will use your C++ code to create a tree in its unmanaged form.
Use getNodes() to convert the tree from unmanaged to managed form.
Return the result to the caller in C#.
your declaration will look something like this, where the Node is your managed calss, ref keyword signifies that the class is managed, and ^ is the managed version of *.
public ref class noderizer
{
public:
static Node^ getNodes(String ^mStr);
};
Here getNodes() calls your C++ function and does the data conversion. I don't think it will take you long to figure it out.
Once you get a hang of the syntax, I think you will find it quite intuitive to use if you are already familiar with C# and C++.
As for performance, unless you're making thousands of consecutive calls or need critical real time data, it should not be an issue. One thing I would say though, if you're concerned with performance, you should write the pure C++ code in a separate purely unmanaged dll. I can't find the article for the life of me, but I remember looking at some benchmarks of executing purely unmanaged long running code block that was compiled inside the C++/CLI dll vs calling the exact same code that was compiled inside its own purely unmanaged dll. If I recall correctly, the separate dll was something like 3x faster.

Using vc++ Dll in C#

I am working on a c# crawler/Poster project, it crawls wordpress blogs, sites, using WebClient to download content.
Wordpress sites use a bug or i don't know, of WebClient, for some reason it does not accept all cookies, from wordpress blogs, it may be a measure to stop auto bots, spammers.
So decided to use Sockets, but seems sockets also has a few problems, it sometimes does not return full response, so not reliable, but i found a good working code in VC++, i am trying to use it in C#, but i dont know vc++ at all.
Here is the code
How do i create a dll of the above code?
I have created a simple dll project using vc++ but unable include the above code in the project.
Updated Link to Code
You can use platform invokes, creating a declaration for each function you need. Here's an example of importing the MessageBox WinAPI function (note that this is not the same as the MessageBox class in .NET!)
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
Now that I have downloaded your code, I can say this...
Even if we got this code to compile, we still have to do the normal heavy lifting of interop between C++ and C#. And the code isn't even ready for that. The http_download.h file is a big set of inline classes. And the instructions for making C++ Code invokable from C# is to long to list here. You would basically have to get this code to compile as a DLL. Then from the DLL either export a set of "C" functions that invoke your C++ to do what you want. Or convert these C++ classes into COM objects with a type library.
But let's analyze what you are really trying to do:
You want to crawl web pages, but WebClient doesn't work.
So I think the real question you want to ask:
Why doesn't WordPress accept my cookies with WebClient?
And I really don't know the answer, because you haven't shared your WebClient code or elaborated what you think may be the issue. But I bet it's an easily solved problem.
I'm certain WebClient will be 10x easier to use than than some C++ code hacked up as one .h file that doesn't look very pretty. And it will be 100x time easier than trying to put together a HTTP library using pure sockets (which is what WebClient is, but it supports all the features you need, but haven't realized yet).
Sorry if I'm curt. I'm trying to encourage you to think about this a better way than doing it the hard way.
Create a class library by using the C++ code and add it as a reference to your C# project.

talking to C from C#

I have a legacy code implemented in C (not C++). I would like to be able to call a few methods in this C code from my C# code (on Windows). What would be the best approach to interface between the two language? Please note that the method in C is not stateless. We need to call two methods:
initialization() => this will initialize the data structure and load data from files into memory. This method will be called once.
ComputeSomething(parameters) => there will be several calls from C# to this method.
Note: These two methods actually call several other methods but these are only the two methods that we would like to expose to C# (the code is quite complicated, that's why we do not want to port to C#)
I have been able to import the c code into visual studio and able to compile the code successfully. I know that we can probably implement the C code as windows service but I am looking for a solution that allow us to call C method from C# directly. Any pointers is highly appreciated! (is COM interop related to what I am looking to do?)
Sounds like you can use P/Invoke for this. Check out this site for tips:
http://www.pinvoke.net/
Also, try searching SO for advice on P/Invoke and Google for
c# pinvoke calling c code
I don't have any technical examples at hand, but I have written some .NET code which called Win32 API's via P/Invoke. The tricky part is getting the method signatures correct when passing parameters. This might help you out there.
Recent version of Visual Studio allow you to write C++ code that can call unsafe functions but still interface with CLR managed code. They call this "Implicit PInvoke," or "C++/CLR." Check out the MSDN article "Using C++ Interop" to learn more.
Managed code can't call unmanaged directly, so you need wrapper functions to handle the memory management issues and to translate between .NET objects and the data structures of your application. From the link above, check out the section on "How to: Wrap Native Class for Use by C#."
Here is a solution. The solution allows to call C# function from C by decorating your function with [DllExport] attribute (opposite of P/Invoke DllImport).
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
C# code
class Test
{
[DllExport("add", CallingConvention = CallingConvention.StdCall)]
public static int Add(int left, int right)
{
return left + right;
}
}
C code
int main()
{
int z = add(5,10);
printf("The solution is found!!! Z is %i",z);
return 0;
}

How to share a class in a Visual C++ DLL with C#?

I wrote my program in C++ and exported it as a DLL. I have a C# WPF GUI and I want to import the DLL to do the processing.
I am very new to C#. How can I use the C++ class in C#? I know I can't just use the .h file.
Because I used pointers in C++, in C# I couldn't use pointers. That's why I got confused. Like in C++ i used char* instead of string, and I need to return double* for a big collection of double data, and things like that.
There are a number of ways:
Export the DLL functions and use DllImportAttribute to P/Invoke into the DLL.
If it is a COM DLL, then you can generate a Runtime Callable Wrapper via TLBIMP.exe
You can use C++/CLI to build create a .Net assembly which loads and calls methods on the DLL natively.
To address your additional concerns, yes, you can use pointers in C#. If you have a function which has a double* parameter, you can declare that in C# like this:
[DllImport("Your.DLL")]
private static extern unsafe void DoProcessing(double* data, int dataSize);
You need to make sure you check the "Allow Unsafe Code" checkbox on the build tab of the C# project, and after that, you can use pointers to your heart's content.
However, note that while I'm providing the pointer signature here, since you are obviously comfortable with pointers, there are other signatures which could be more safe for you to use, and would not require you to compile C# with unsafe code. The standard marshaller in the CLR will take care of the conversion from a pointer to a C# array, provided you give it a bit of a hint if the length is required:
[DllImport("Your.DLL")]
private static extern void DoProcessing(
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] double[] data,
int dataSize);
This instructs the marshaller to use the parameter at index 1 (the 2nd parameter) as the size of the array of doubles pointed at by the 1st parameter. This allows you to avoid pointers in C#, and use safe CLI types. However, if you like pointers, my advice is to just use them - the C# will be easier for you than having to figure out how to write the method signature without them.
For more details on P/Invoke, refer to this documentation: http://msdn.microsoft.com/en-us/library/aa288468(VS.71).aspx
A lot depends on the structure of your C++ dll. If you have just a handful of functions, and they are not member functions of a class, then you can make them "extern C" functions and use the P/Invoke capability in .NET (sometimes called DllImport because of the attribute you use) to access the functions from C#.

Is it possible to use win32 DLLs in C#?

I have win32 DLL named VssSdkd.dll. It contains two classes with names VssSdkServiceLogin and VssSdkMsg.
I need to import the VssDskServiceLogin class, in C#. I am setting few properties of VssDskServiceLogin object and passing this to VssSdkMsg which in turn invokes some other method.
How can I achieve this using C#.
I have win32 DLL named VssSdkd.dll. It
contains two classes with names
VssSdkServiceLogin and VssSdkMsg.
In C#, I need to import the
VssDskServiceLogin class. In the class
are some attributes I need to set the
value for, sending the information to
VssSdkMsg and call another function
I need to achieve those things through
C# code. Is this possible, and if so,
how?
Classes compiled in C++ (and other Win32 languages) cannot be interoped with Dot NET languages. Structures may be if care is taken. Dot NET does have support for COM objects, though.
Native functions may be called from Dot NET languages if they're tagged with the [DllImport] attribute on the CLR side (and the appropriate DllImportAttribute properties are set) - and exported on the Win32 side. However, this is a non-trivial process. I would recommend grabbing a good book on the subject and starting from the top. SO is probably not a very good medium for addressing this issue.
You can do it with p/invoke and marshaling. Read about it, it's too complicated a subject to explain fully in a SO answer.
I believe it is sometimes possible in C# through P/Invoke, but when dealing with classes, this can get very, very difficult.
I'd highly recommend creating a C# wrapper for your DLL using Managed C++ instead.
I don't know that this link will solve your problem directly, but I expect you can find a good example of how to do this at Code Project. Managed C++ can be a little tricky until you get used to it, and I think the syntax changed from .NET 1.0/1.1 to .NET 2.0. Make sure you know what version of .NET you're targeting and search the Code Project site accordingly.
Possibly what you are looking for is interoperability with COM.
I haven't worked much on it, but can give you a sample code to start with.
[DllImport("user32.dll")]
private static extern int MessageBox(IntPtr hWnd, String
text, String caption, uint type);
static void Main(string[] args)
{
MessageBox(new IntPtr(0), "Hello, world!", "My box", 0);
}
This may be of help.

Categories