I have a c dll, which is an api which exposes many methods. I want to replace this dll with one written in a more up to date language. However, I have customers who have integrated to the c dll already, and I want to just give them the new c# dll which replicates the c dll. I need to do this in such a way as the customers who have integrated to the c dll are not affected at all. i.e. I just want to replace the c dll with the c# one, and it should seem seamless to them.
Is this technically feasible? And if so, how should I go about replicating the c interface in c#.
I have a number of methods in the c dll is defined with dllexport
__declspec( dllexport ) void __stdcall
You can't do that with a C# dll. You would have to write a COM wrapper for the managed dll, and client code would then have to link against the COM wrapper's type library (*.tlb).
You could do that with C++/CLI, by building a mixed-mode dll that exposes the native interface to unmanaged code. Then you would just distribute the dll and the .lib file like normal, and client code would just link against the .lib file (as it presumably does now).
That's a fair bit of work, though. Unless there is some problem with the original C dll, I don't think I would go to the trouble.
Related
I have a c++ project compiled with /clr support(e.g. wrapper.dll). This project(wrapper.dll) is a wrapper between .Net enviroment and unmaged dll(e.g. noCode.dll), which inherits from. I dont have access to code of inherited dll(noCode.dll), but I can link it to my wraper (by noCode.lib and noCode.h files).
When I want to use my wraper(wrapper.dll) in c# project I reference it and have to copy my unmanaged dll(noCode.dll) to location of c# project execution.
Is it possible to merge c++ unmamaged dll(noCode.dll) to managed dll(wrapper.dll) to allow to use only one file by reference(noCodeWrapper.dll) in c# projects?
It is not possible to link DLL files together.
But you can add that nocode.LIB to your DLL and then you don't need [DllImport]. Since you have LIB and H files, you can call the "nocode" functions directly from your managed C++ code.
If you had access to noCode.dll source code you could integrate it with wrapper.dll. Otherwise merging DLL binaries is not a task that could give predictable results.
I'm working on a C# component which consists of two DLLs:
A .DLL written in C++/CLI exporting a symbol; unfortunately, this DLL dynamically links against the CRT and there doesn't seem to be a way around that.
A C# assembly.
The C++/CLI DLL gets loaded and then loads the C# assembly (and forwards most calls to it). Is it possibly to simplify this scenario so that I export a symbol from the C# assembly right away?
You can export your functionallity from C# as a COM server this way it should be pretty easy to call it from C++ as you would do with any other non-C# COM object.
I ended up going for the solution described in http://www.codeproject.com/Articles/37675/Simple-Method-of-DLL-Export-without-C-CLI
The general approach is to have a dedicated attribute which is used to decorate the functions to be exported. After building the assembly, ildasm is used to disassemble it. The resulting IL is patch a little bit so that the previsouly decorated functions are exported, then the IL is assembled into an assembly again.
I have windows form application written in VC ++ . I want to change the button click in this app (WInform app in VC++) to hit a function written in C#.
What are the possible ways to do this.
Calling a C# assembly without compiling with C++/CLI is tricky. some of the ideas I've had:
a) Create a mixed-assembly wrapper dll (mixed assemblies contain both native code and managed code). Add a reference to your C# assembly, then create functions in your dll that call the C# code via C++/CLI, then define dll entrypoints ( __declspec(dllexport) ) for those functions. You can now link against the dll as it will provide a native interface that C++ can understand, while internally that dll can call your C# code.
( Afterthought: You can probably compile this to a .lib, that would be easier than a dll.)
Walkthrough: Creating and Using a Static Library
b) Use Mono to call the C# assembly. Mono has a C API which you can use to load and use managed assemblies without using c++/CLI. This is what I would do if C++/CLI is not an option.
Embedding Mono
c) If your function has a relatively simple input/output signature (no large objects, etc) you might consider compiling your C# function into an executable and use standard input/output to call the function. You'll have to carry input arguments and the output as text, though. Then make C++ start the executable and pass some input to it, and read the output.
I need to write a .NET dll that can be called directly from an Excel's VBA Module such that the dll and .xls are simply deployed in the same directory without any COM registration.
Purpose of dll is to run algorithms implemented in C.
How should I proceed? Is this possible at all?
You don't explain what the role of .NET would be in your scenario. You can indeed call many C libraries directly from VBA using 'Declare Function'.
If you find .NET useful, and want to call your .NET library functions as user-defined functions (UDFs) from Excel, you can use Excel-DNA. It gives you an .xll add-in library that integrates your .NET library into Excel. You'd still have to open the .xll add-in somehow - either by File -> Open, by adding it as an Excel add-in, or automatically from some VBA in your workbook. But it needs no other registration.
From the .NET library you can call the C .dll functions using P/Invoke, add categories, function and argument descriptions to integrate into the function wizard etc.
(Disclaimer: I'm the developer of Excel-DNA.)
Have you seen this MSDN article? Basically you register functions from a DLL, not a DLL itself. I don't know if it is put very clear in the article, but the syntax is:
[Public | Private] Declare Function name Lib "libname" [Alias "aliasname"] [([arglist])] [As type]
where "libname" can contain full path e.g. "C:\tmp\algo.dll" or only a name e.g. "algo.dll". In the second case the local path will be searched for a matching binary.
If the DLL contains C functions then you should avoid .net and the CLR. That's a needless overhead.
Instead use a C compiler, MSVC for example, to build the DLL and export the functions you need from that DLL. Then import the DLL functions into VBA with Declare statements.
When you build the C functions into a DLL make sure that you use the __stdcall calling convention since that is the only option with Declare. You may also need to use a .def file when building the DLL to avoid name decoration.
A very simple example:
C
int __stdcall add(int a, int b)
{
return a+b;
}
VBA
Public Declare Function add Lib "mylib.dll" (ByVal a As Long, ByVal b As Long) As Long
I am wrote a visual c++ win32 console app, and i wrote it and tested it in
win32 console project
. then i switch to
win32 project
and imported all the source files and created a dll for it. by mark the class i want to export as
#define DllExport __declspec( dllexport )
class DllExport theClass {
}
it works and the dll is generated. then i created a another c# project and want to add the dll to the project. by reference->add reference-> browser. then i select that dll.
then it is gives me an error
a reference to the '''''''.dll could
not be added. please make sure that
the file is accessible, and that is a
valid assembly or com component.
anyone knows where i did wrong to generate/import the dll?
thanks
The Add Reference dialog can only work for DLLs that contain metadata (managed code) or a type library (a COM server). Your DLL doesn't fit that bill, you can only use the [DllImport] attribute in C# code to use the P/Invoke marshaller to call an unmanaged DLL entrypoint.
That can not be a native C++ class, like you are trying to do, there is no reliable mechanism for managed code to allocate unmanaged memory and call the constructor (and destructor) of a native C++ class. Short from the difficulty of finding the constructor and destructor code, there is no way for the P/Invoke marshaller to know the size of the object. The C++ language doesn't generate the metadata necessary to know this required information.
If you want to pursue P/Invoke then write an plain global function, decorated with extern "C", __declspec(dllexport) and (optionally) __stdcall.
If you want to export a C++ class then the only avenue is using the C++/CLI language and write a "ref class" wrapper for the native C++ class.
Or you could write a COM coclass, the universal glue in Windows. Very well supported by .NET, probably not something you want to pursue if you never wrote COM code before. ATL is the best way to get one going.