I am attempting to connect to a commercial server application, which only has a C# API.
I would imagine that the best approach for doing so would be to create a C# DLL - which is what I have done. However, when examining the methods contained within the DLL utilising 3rd party tools, the methods do not seem to be visible.
I have searched extensively on StackOverflow, and found that the following suggestion works for most people - however the methods are still not visible when utilising this extension.
Thus it may be time to seek an alternate approach to how this problem can be solved - one option could be a C# console application.
Any ideas regarding what would be the best approach?
EDIT:
After running the DUMPBIN program, this is the output:
C:\Program Files (x86)\Microsoft Visual Studio 11.0>dumpbin /EXPORTS "C:\Users\mark\Desktop\Test.dll"
Dump of file C:\Users\mark\Desktop\Test.dll
File Type: DLL
Summary
2000 .reloc
2000 .rsrc
2000 .text
If the Basic+ has an option to call C code, you have an option to create a project in Managed C++:
Exports some function decorated like:
extern "C"{
__declspec(dllexport) void _cdecl MyFunction()
{
_MyImpl(); //see below wy this
}
}
void MyImpl()
{
MyCSharpObj^ test = gcnew MyCSharpObj()...
test->Methods(...
}
Outside of the portion decorated with extern C you can safely call and mix managed and unmanaged calls. The reason you should go outside the extern C block is that almost all managed function have overloads, and Extern C does not support method overloading even in call.
You can call c# by just adding references ( actually you can write all your code in managed C++, but is not so friendly ) to your .NET libraries.
Basic+ seems to be made by Revelation Software.
On this page, it says:
OpenInsight 9.1 released
This new OpenInsight release included a
couple of .NET innovations. NetOI enables developers to code using
their Microsoft Visual Studio licenses and work against an OpenInsight
database. The RevDotNet functionality provides a method of calling
.NET APIs and using the .NET controls within an OpenInsight
application.
Can you use RevDotNet to call your C# APIs directly?
Related
Consider the following two (randomly chosen, just because I happen to use both of them in the project that I have currently open) example API calls, both contained in Microsoft libraries:
LocalDBCreateInstance
OpenPrinter
The first one needs CallingConvention.Cdecl when P/Invoked through the DLLImport attribute, the second one needs the default value WinApi/StdCall.
Currently, I use one of the following techniques to find out which one to use:
Guess: If it's built-in Windows API, it's probably StdCall, otherwise it's probably Cdecl.
Research: Find the SDK containing the header file, install the SDK, search my whole hard drive to find that header file buried somewhere deep inside some obscure folder, and then look inside and check the function declaration.
Is there an easier way? For example, is there some reliable way to deduce the calling convention from the MSDN documentation link of the API method (see the two examples above)?
Checking the header files is the right thing to do.
Step 1: Find out which header file you need. Both examples you mentioned have information about the required header file on their documentation page (msoledbsql.h and Winspool.h, respectively).
Step 2: Get the header file. You can do this by installing the SDK containing the header file, but, as you point out in your question, it can be a hassle to find the SDK, download it, find its installation location, etc.
However, chances are that you are not the first one to use that API method and that the header file can be found in a public repository. Querying Sourcegraph, for example, for LocalDBCreateInstance msoledbsql.h and OpenPrinterW file:winspool\.h$ will yield the relevant information as the very first result.
HRESULT __cdecl LocalDBCreateInstance(PCWSTR wszVersion, PCWSTR pInstanceName, DWORD dwFlags)
BOOL WINAPI OpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefault);
Other alternatives for C# developers include:
Download the Win32 metadata file and find the correct C# DllImport specification with ILSpy.
Use the C#/Win32 P/Invoke Source Generator to auto-generate Windows API declarations in your code.
Those are official Microsoft projects, so the information is likely to be accurate. Note, though, that they will work only for built-in Windows API methods (so they would help with OpenPrinter but not with LocalDBCreateInstance).
(Kudos to #The2Step and #Simon Mourier for teaching me about Sourcegraph and win32metadata/CsWin32 in the comments.)
I want to integrate MATLAB Coder output with a C# project in Visual Studio 2010. My main idea is:
Create a *.m script in Matlab
Make sure the script is compatible with Matlab Coder.
Generate a C++ shared library (DLL) with Matlab Coder
Integrate with C# using something like this:
//Starts the model execution. May take several minutes
public static class DllHelper
{
[DllImport(#"test.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint = "Run()")]
public static extern int Run();
}
Also, I would like to be able to stop the execution and retrieve some partial results. To do this, I was thinking in two methods: StopExecution and RetrievePartialResults
[DllImport(#"test.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint = "StopExecution ()")]
public static extern int StopExecution ();
[DllImport(#"test.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint = "RetrievePartialResults()")]
public static extern MyResults RetrievePartialResults();
Is it possible to do? If no, is there any alternatives? If yes, where can I find more examples?
I have no idea if your plan works, but MATLAB Builder NE might be an alternative. It directly outputs a .Net dll without those hard limitations to the m-code.
The disadvantage is, that MCR is required on the target machine.
I've done both ways. Formerly, our project was using MATLAB Compiler, but we now switched to Coder, because that avoids the overhead of having to install the runtime (which btw often failed to start inside the process for no apparent reason).
We compile the coder output as an unmanaged C project with a C interface and use a C++/CLR project as a wrapper. This has the advantage that we don't need to manually specify the interface for P/Invoke as the compiler will directly read the header files. The C++/CLR assembly is the linked to the C# project where the code is going to be used. Be aware that this is kind of expensive, so try to avoid calling the matlab code in a tight loop and better move the whole loop into the library if that is possible.
Here's a snippet from the wrapper library (still uses old Managed C++ syntax, but that doesn't matter here)
bool CTurconConnect2::Init()
{
// Call the exported function in the library. Imported using a header file.
turcon_initialize();
// Call one of the matlab functions (in this case, the entry function is manually defined
// in the C library, to have a clean interface)
SetParameters(36.0,400.0,20.0,30.0,15.0,40.0,110.0, 0.0, 100.0);
return true;
}
bool CTurconConnect2::Exit()
{
turcon_terminate();
return true;
}
I think your plan of writing a DLL and calling it from c# seems to be one of the two main ways to go.
The alternative would be to:
use the MATLAB as an automation server from C# using the engine
interface via com automation. This allows you to simultaneously debug
your C# application from both the C# side and the MATLAB side, using
debuggers on each side.
Here are examples for both methods, and even a third alternate method (that seems less recommended).
Integrating MATLAB with C# on File Exchange
I've achieved the exact functionality you're asking about using the MATLAB Compiler. I don't have any experience with the MATLAB Coder, but should be the same principle. Once you have a MATLAB Library compiled, you can access it using P/Invoke in C# like you would with any other unmanaged library (and as you specified in your question).
Theres a couple of caveats:
I think you might have an issue design-wise trying to successfully implement your "stop execution" strategy. The MATLAB executables/libraries are meant to execute from start to finish without much control over the runtime. If you can split your script up into multiple pieces to handle that design, that may work better.
Compiled MATLAB libraries require you to "Start" and "Stop" the MATLAB Component Runtime manually, as well as a component runtime for each script. So, execution flow, would be something like:
StartMCL();
StartScript1_Runtime();
Run_Script1();
StopScript1_Runtime();
StopMCL();
If you attempt to run the "Script 1 Runtime" prior to starting the overall MCL, the app will crash. So, you need to be careful with how you design the wrapper class to handle that properly. Also, you want to be sure to Stop everything before exiting your app, otherwise, the MCR will effectively see 2 "Runs" in a row, and will crash.
You didn't cover any input/output arguments in your question, but in most cases, you will need to use MATLAB functions to create the MEX variables to hand data in/out of the MATLAB environment.
There is a great set of sample source here that should cover all of the above:
http://www.mathworks.com/matlabcentral/fileexchange/12987-integrating-matlab-with-c
Also, the Compiler help itself has a bunch of useful resources.
http://www.mathworks.com/help/compiler/shared-libraries.html
So in a list form,
I doubt that you will be able to stop the matlab code unless you break it up into multiple functions, which you may call as needed.
That you should be able to halt execution by calling on a thread and stopping the thread as you need, or better, send a signal for the thread to stop, which it will abort between functions (for the purpose of partial results)
That matlab is a terrible language for fulfilling the requirements on item 1 (not that I have ever had any good experiences with it myself)
I need some help now. I would love if someone could help we with "transferring" my QT based code to work with my C# application.
Lets say I have this simple QT Class:
class ItShouldWork : public QObject
{
Q_OBJECT
public:
ItShouldWork(QObject* parent = 0) : QObject(parent){}
QString id() const { return objectName(); }
};
Now I want to be able to access this class with Visual Studio C#, I've tried creating an unmanaged dll and access through an wrapper, tried to create an COM component but right now I'm completely stuck so I'm going back to the beginning with this simple class. I've seen that you can use an extern "C" with __declspec(dllexport) like this:
extern "C" __declspec(dllexport) double Subtract(double a, double b)
and then use _dllImport in .net, this works fine with the function above but when adding for example a QString to it it doesn't recognize my dll anymore and a dllNotFoundException is thrown.
Then I thought maybe you need a wrapper of some kind, yeah and how do you do that then..? googled away but nothing to really help me with c++ and qt functions.
A small step by step on how creating a dll and a c-wrapper or creating a COM component dll directly would be awesome, I don't really care how it's done but if you know a way, please help me with a small tutorial? I'm going crazy...
C++/CLI is the way to go, I think.
See: Wrapping unmanaged C++ with C++/CLI - a proper approach
And especially: http://www.delmarlearning.com/companions/content/1592009638/bonus/009638_BonusCh02.pdf
Going into that subject in depth is not easy to do in a forum post. But with some research you should be able to create something useable quite quickly.
C++/CLI takes some getting used to, if you're coming from C/C++. It's a bit more restrictive, especially regarding mixing managed and unmanaged types. But the literature will guide you there.
EDIT:
In response to OP's comment to my answer(also see Comment by Ramhound, Me), here is an example I got here:
Have a look at the content behind the link to see the context of m_impl...
String ^ CSimpleObjectWrapper::ToString(void)
{
wchar_t szStr[100];
HRESULT hr = m_impl->ToString(szStr, ARRAYSIZE(szStr));
if (FAILED(hr))
{
Marshal::ThrowExceptionForHR(hr);
}
// Marshal PWSTR to System::String and return it.
return gcnew String(szStr);
}
EDIT 2:
Also depending on the desired depth/complexity/power of your wrapper, you might think about wrapping your classes in C++/CLI "ref class"es instead of using DllImport.
You can create wrapper on Managed C++. Then you will be able to use managed classes in c#. Check this, it might help you http://msdn.microsoft.com/en-us/library/ms235638.aspx
Take a look at http://doc.qt.nokia.com/4.7-snapshot/activeqt-dotnet.html. It has some information on using ActiveQT, which per the website:
Qt's ActiveX and COM support allows Qt for Windows developers to:
Access and use ActiveX controls and COM objects provided by any
ActiveX server in their Qt applications. Make their Qt applications
available as COM servers, with any number of Qt objects and widgets as
COM objects and ActiveX controls.
The page also has examples on how to integrate with .Net.
I have used reflector until its trial period ended
I have decoded many applications successfully. And by my recent post i was able to identify it can also decode delphi.net vcl apps (d2007).
Can i decode delphi.net vcl and translate it to a c# application which can be compiled success fully using visual studio.
The answer to the question Can i decode delphi.net vcl app and translate it to a c# application which can be compiled success fully using visual studio ? is No
This is the Why.
When you create a vcl net application using delphi (8), 2005, 2006 or 2007, the delphi compiler create an .NET application with a lot of dependencies to internal classes which are wrappers and helpers to call the real .net classes, these classes (wrappers) was created to facilitate the creation of .net applications to the existing delphi win32 developers.
Consider this sample.
This a delphi .net app
program DelphiNetConsole;
{$APPTYPE CONSOLE}
uses
SysUtils;
begin
try
Writeln('Hello From Delphi 2007.Net');
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
if you translate manually this code to C#
using System;
using System.Text;
namespace ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Hello From Delphi 2007.Net");
}
catch (System.Exception E)
{
Console.WriteLine(E.Message);
}
}
}
}
But using reflector you get this for the first snippet
public static void DelphiNetConsole()
{
System.IsConsole = true;
try
{
TextOutput.Output.WriteWideString("Hello From Delphi 2007.Net", 0).WriteLn();
System.#_IOTest();
}
catch (Exception exception1)
{
Exception exception2 = System.#ExceptObject = exception1;
Exception E = exception1;
TextOutput.Output.WriteWideString(TObjectHelper.ClassName(System.#GetMetaFromObject(E)), 0).WriteWideString(": ", 0).WriteWideString(E.Message, 0).WriteLn();
System.#_IOTest();
System.#ExceptObject = null;
}
}
As you can see the last code call a lot of helper classes and functions (like TextOutput) which are not part of the standard .net framework, rather they are part of the Borland.Delphi.System namespace.
Reflector can help you to translate some snippets of code but not the full application in an automated way.
The answer is no, and even if you deploy the corresponding Delphi assemblies, such as Borland.Delphi.dll and Borland.Vcl.dll, you have structures that have no equivalent in C#, such as class references, that cannot be used within Visual Studio/C#. I managed to convert about 80,000 lines of a non-visual application framework in Delphi to use in Visual Studio/C#, but it took me over 3 months and I had to convert code that used things like class references to use the System.Type class, amongst other things. After all this work, and with the deployment of some basic Delphi assemblies, an Indy assembly, and a Jcl assembly, I can now develop in either Delphi or Visual Studio and maintain communication compatibility between the two types of applications.
One other thing I did is to run some custom pre-processing of the source code before building to strip of the "T..." type prefix so that the actual framework assemblies look just like C# assemblies when used in Visual Studio. This was no easy task but was made possible by the fact that all types, constants, etc in my framework were ALL prefixed as well by either "Csi", "App", "Fwk", or "Dev". Without this I could not have stripped off the Deplhi-specific identifier naming conventions.
Unless there is an overwhelming benefit for doing this which outweighs the cost (like me), and your code is essentially non-visual (like me), the amount of effort involved is likely to be far too great to justify the work. I wonder if I am the only Delphi developer in the world to succesfully have migrated a significant amount of code from Delphi for use in Visual Studio. Nobody else seems to be able to provide a success story like this, which really makes you wonder how feasible this is.
This is to all the C# gurus. I have been banging my head on this for some time already, tried all kinds of advice on the net with no avail. The action is happening in Windows Mobile 5.0.
I have a DLL named MyDll.dll. In the MyDll.h I have:
extern "C" __declspec(dllexport) int MyDllFunction(int one, int two);
The definition of MyDllFunction in MyDll.cpp is:
int MyDllFunction(int one, int two)
{
return one + two;
}
The C# class contains the following declaration:
[DllImport("MyDll.dll")]
extern public static int MyDllFunction(int one, int two);
In the same class I am calling MyDllFunction the following way:
int res = MyDllFunction(10, 10);
And this is where the bloody thing keeps giving me "Can't find PInvoke DLL 'MyDll.dll'". I have verified that I can actually do the PInvoke on system calls, such as "GetAsyncKeyState(1)", declared as:
[DllImport("coredll.dll")]
protected static extern short GetAsyncKeyState(int vKey);
The MyDll.dll is in the same folder as the executable, and I have also tried putting it into the /Windows folder with no changes nor success. Any advice or solutions are greatly appreciated.
I have the same problem, but this time there is no obvious difference in the platforms involved. Why is it something that is supposed to be 'normal' is so badly documented, so difficult and worst of all so 'flaky'.
Are there ANY tools that allow me to go onto my PPC emulator, and stop by step check (a) that the dll is where CLR expects it (I have put it both in the same directory, and the windows directory on the emulator - I can see it is there usign the emulators file explorer), (b) that CLR can load it (has enough memory etc), (c) that CLR can then find what functions are present (useful if I can get beyond the stupid 'can't find the dll' error)
I'd love to force Gates or indeed any of the 'windows mobile' team to use the crap they create.
Maybe this seems like an obvious thing to check, but are you compiling the native DLL for the correct CPU architecture? IIRC, Windows Mobile runs on multiple CPU architectures.
The exception you listed and the pinvoke signature you put in the question have different names: MyDll.dll and ThreadBenchLib.dll respectively. Was that a typo or the problem?
If it's not the problem try opening the DLL in depends. It's possible the DLL load is failing because of an unmet dependency.
I am having the same problem. I used the Depends.exe to look for WinCE dll dependencies, and It depends of debug dll. (MSVCR90D.dll)
To solve the problem I compiled a release version, and confirm the dependencies, after that it works fine.
I hope to help