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.
Related
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.
These codes will set the windows calculator into a windows form application. But the question is how to use the NativeMethods.SetParent in the third line. Does it have special namespace?
System.Diagnostics.Process p = System.Diagnostics.Process.Start("calc.exe");
p.WaitForInputIdle();
NativeMethods.SetParent(p.MainWindowHandle, this.Handle);
Please help me to use NativeMethods in the third line.
Any help will be appreciated
I presume you are trying to "embed" the calculator within a WinForm? If so check out the following pinvoke method:
[DllImport("user32.dll")]
internal static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
http://www.pinvoke.net/default.aspx/user32.setparent
To embed the calculator window into a WinForm (or another control such as a Panel), just pass the Control.Handle as the second parameter.
There is no public NativeMethods class in .NET. It is considered good practice to put calls in a NativeMethods class, so this is probably what you are seeing.
You need to use P/Invoke to call Win32 API functions. See this tutorial.
stakx is onto something with his comment:
An obvious starting point would have been to study the original source of that line of code. Where did you copy it from? Can you find the declaration of NativeMethods.SetParent in the original source? (No need to answer, this is meant as a suggestion of what I would have done in this case.)
This is exactly the way you need to solve such problems.
The code snippet shown in the question was in fact copied from here. No, it doesn't compile when you copy and paste it into your project. It was never intended to. I wasn't trying to write a complete demo, but rather provide a brief sketch of what the required code might look like were you to write it yourself.
You do have to read the whole answer, not just the part with the light gray background. I know we're all programmers so we often think that we can understand everything just by looking at the code, but that's an unfortunate lie. I provided a link to the Windows SDK documentation for the SetParent function; you'll have to read that documentation, understand what the function does, and then write the P/Invoke declaration so that you can call it from your C# code.
Like Kendall says, calls to native Win32 functions are placed in a static class called NativeMethods, both by convention and by explicit recommendation from .NET design guidelines (enforced by tools such as StyleCop). My sample was following this common practice because I assumed .NET developers interested in Win32 interop would be familiar with this convention and follow it themselves when writing the P/Invoke definition.
As Nate alludes, some people find the website http://pinvoke.net/ to be a useful resource when writing P/Invoke definitions for Win32 functions. And it can often be. But you do have to make sure that you're not just copying and pasting code from there, either. I've seen a surprisingly large number of mistakes in the samples that they provide (and answered more than my fair share of Stack Overflow questions from people whose apps blew up when they used the incorrect code they copied from that website). You need to understand what the code you're using is doing and how it is supposed to work. Not only does that ensure you can catch any mistakes that it may contain, but it also keeps you from introducing serious bugs or worse, security holes, into your application.
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.
[DllImport( "zlib32" )]
private static extern ZLibError compress2(
byte[] dest,
ref int destLength,
byte[] source,
int sourceLength,
ZLibQuality quality
);
every time I call this I get an MDA warning telling me the stack is imbalanced, which is a nightmare for debugging. I want to either turn this warning off, or fix the issue
This MDA raised to tell you that you have a problem with parameters type you are using for PInvoke call. Generally, it is very bad idea to turn it off since it warns about problem in your code and imbalanced stack leads to errors (sometimes hard to find) in future.
Usually, common mistake is selected matching for unmanaged type with managed one.
In your case, original defininition (I take a look to zlib125.zip):
ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen,
int level));
which can be traslated to if library was compiled with 64-bit support for unsigned long:
static int compress2(
byte[] dest,
ref ulong destLength,
byte[] source,
ulong sourceLength,
int level)
Ensure ZLibQualityenumeration is based on int. Probably, your error is usage int instead of ulong for both lengths.
As stated David Heffernan there are plenty other reasons to fail to find exact one give us link to library actually used for development if you still want to know.
traditional compilation original library with Visual C++ will result you get library with 32-bit support only, so original definition you provided in question is valid unless ZLibQuality enumeration is not int based
maybe you try to use library compiled for other calling convention such as cdecl instead of stdcall
maybe you try to use modified library where compress2 function takes additional parameters.
We can find whats wrong when we can see exact library you are using.
long or unsigned long usually 32-bit under Windows and mapped to int or uint respectively. Since you have troubles with original declaration I assumed that maybe you are using specific library with 64-bit support. Thanks to David Heffernan to point me makes my notice clearly.
You can use folowing resourses as reference:
A wiki for .NET developers - PInvoke.net is primarily a wiki, allowing developers to find, edit and add PInvoke* signatures, user-defined types, and any other information related to calling Win32 and other unmanaged APIs from managed code
PInvoke Interop Assistant
/Offtopic:
Why do you use you own implementation with self bindings to library? You can use:
DotNetZip - Zip and Unzip in C#, VB, any .NET language - DotNetZip is an easy-to-use, FAST, FREE class library and toolset for manipulating zip files or folders. Zip and Unzip is easy: with DotNetZip, .NET applications written in VB, C# - any .NET language - can easily create, read, extract, or update zip files. For Mono or MS .NET.
or ready to use 7-zip bindings: SevenZipSharp - Managed 7-zip library written in C# that provides data (self-)extraction and compression (all 7-zip formats are supported). It wraps 7z.dll or any compatible one and makes use of LZMA SDK.
The stack imbalance is because you have mis-matching calling conventions or mis-matching function declarations. I'd be very surprised if zlib32 was using stdcall calling convention. Surely that uses cdecl. I'd want to see your C++ declaration of that function before giving firmer advice.
Leave the warning on because it's finding bugs in your code, and fix the mis-matches, whatever they are.
There could be a real issue here, but I usually have to disable all Managed Debugging Assistants every now and then, since some of these magically get enabled. Be sure to check Debug | Exceptions node, then expand the Managed Debugging Assistants and make sure every one of these is disabled.
EDIT: You will have better luck replacing the P/Invoke with a C++/CLI wrapper that you create for compress2.
I have a Delphi DLL with a function defined as:
function SubmitJobStringList(joblist: tStringList; var jobno: Integer): Integer;
I am calling this from C#. How do I declare the first parameter as a tStringList does not exist in C#. I currently have the declaration as:
[DllImport("opt7bja.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int SubmitJobStringList(string[] tStringList, ref int jobno);
But when I call it I get a memory access violation exception.
Anyone know how to pass to a tStringList correctly from C#?
You'll most likely not have any luck with this. The TStringList is more than just an array, it's a full-blown class, and the exact implementation details may differ from what is possible with .NET. Take a look at the Delphi VCL source code (that is, if you have it) and try to find out if you can rebuild the class in C#, and pass it with the help of your best friend, the Interop Marshaller. Note that even the Delphi string type is different from the .NET string type, and passing it without telling the marshaller what he should do, he will pass it as a char-array, most likely.
Other than that, I would suggest changing the Delphi DLL. It's never a good thing to expose anything Delphi-specific in a DLL that is to be used by non-Delphi clients. Make the parameter an array of PChar and you should be fine.
If this is your DLL, I'd rewrite the function to accept an array of strings instead. Avoid passing classes as DLL parameters.
Or, if you really want to use a TStringList for some reason, Delphi's VCL.Net can be used from any .Net language.
An old example using TIniFile: http://cc.codegear.com/Item/22691
The example uses .Net 1.1 in Delphi 2005. Delphi 2006 and 2007 support .Net 2.0.
If you don't control the DLL and they can't or won't change it, you could always write your own Delphi wrapper in a separate DLL with parameters that are more cross-language friendly.
Having a class as a parameter of a DLL function really is bad form.
I am not exactly clear your way of using delphi and C#. It seems you have created a Win32 DLL which you want to call from C#. Offcourse you must be using PInvoke for this.
I would suggest that you create a .NET DLL using your source code since complete porting of VCL is available. I can further elaborate if you wish....
In theory, you could do something like this by using pointers (casting them as the C# IntPtr type) instead of strongly typed object references (or perhaps wrapping them in some other type to avoid having to declare unsafe blocks), but the essential catch is this: The Delphi runtime must be the mechanism for allocating and deallocating memory for the objects. To that end, you must declare functions in your Delphi-compiled DLL which invoke the constructors and destructors for the TStringList class, you must make sure that your Delphi DLL uses the ShareMem unit, and you must take responsibility for incrementing and decrementing the reference count for your Delphi AnsiStrings before they leave the DLL and after they enter it, preferably also as functions exported from your Delphi DLL.
In short, it's a lot of work since you must juggle two memory managers in the same process (the .NET CLR and Delphi's allocators) and you must both manage the memory manually and "fool" the Delphi memory manager and runtime. Is there a particular reason you are bound to this setup? Could you describe the problem you are trying to solve at a higher level?
As Hemant Jangid said, you should easily be able to do this by compiling your code as a .NET dll and then referring to that assembly in your c# project.
Of course, you'll only be able to do this if the version of Delphi you have has Delphi.NET.
I don't know a lot about c#, but a technique that I use for transporting stringlists across contexts is using the .text property to get a string representing the list, then assigning that property on "the other side".
It's usually easier to get a string over the wall that it is a full blown object.