Use C# DLL as COM under Delphi - c#

We got a DLL written by C# programmers, compiled to usable as COM object.
We consult these developers to get the function names, and syntaxes, and we can use it after we registered it with regasm.
This is ok, but we have more questions to produce faster development (on changes), and some things are not understandable or not working.
We used Delphi 6 professional, and assembly made by C# Visual Studio 2008 (as I think).
Let's see them:
1.)
I cannot use the typelib (TLB) of the C# code, because I cannot import into Delphi.
The result was:
"Hiba az OLE beállításjegyzék használata közben."
Translate ~ "Error occured on use OLE typelib/setting lib"
Possible sources of the error:
a.) Delphi 6 cannot import the new COM dll-s.
b.) We must force to C# generate an older formatted TLB.
We tried to re-generate the TLB with regasm, but we also got this error.
May this impossable, but if case b.) happens, what we need to say to C# developers - how to compile the DLL-s?
(DLL-s are unimportable by Delphi, because they don't have self init section).
2.)
Interesting:
All of the parameters correctly converted into variants vica-versa, but if the C# method does not have parameter, I got error in Delphi side...
For example (pseudo):
proc A():bool;
Calling of A is generating an error in Delphi side.
proc A(Dummy: bool):bool;
Calling of A(False) is working fine.
I don't know, why we got this.
What do you thing about this? Is this a C# compiling problem?
Thanks for your help:
dd

Best route here is to obtain source code showing the successful use of the DLL via COM using, say, C#. The developers of the DLL should be able to provide that. The DLL probably also has to be registered with regasm (not regsvr32.exe as it would be for a native COM DLL) before it will be accessible via COM. As always, without more actual code, it is very difficult to answer such questions.

Related

Loading a C# class in R 3.6.x

I have a solution that is built in Visual Studio 2019 using C# 3.5.0. I have my mother application that is coded with RStudio running R3.6.x. My objective is to use the solution (Project files are with me) and integrate with R. The input data flows from R and uses the C# code to produce the intermediate outputs.
My attempts:
1. I tried dyn.load to build the dll but it fails with "module not found" error message.
2. I did not find ".cs" as one the objects accepted by shlib cmd tool for building R loadable dll packages.
2. Tried to install rClr and it failed as there is no library for R3.6.x
So the challenge is to find an efficient way to load the COM object in R 3.6.x. Suggestions welcome.
You might want to take a look at Exporting a C# function. This will only allow c-style function calls. There are also R-Interop that uses named pipes for communication. A third way might be to use Component object model.

How can a C# program use a COM dll of any version?

This question is a sequel of this question
We're creating a dll, written in C++, providing access to some hardware. This dll implements and is accessed using COM interfaces. We also have a C# program that uses this dll through the COM objects.
We're having an issue with the versions. Indeed, when running the C# program, it absolutely wants to use the exact COM/C++ dll version it used when compiling. I.e. if the C# program was compiled using COM/C++ dll 1.2.3.4, then the program will refuse to run with COM/C++ dll 1.2.3.5.
Unhandled Exception: System.TypeInitializationException: The type initializer for 'MyDllVerify.App' threw an exception. ---> System.IO.FileNotFoundException: Could not load file or assembly 'MyCorp.MyDll.Interop, Version=1.2.3.4, Culture
=neutral, PublicKeyToken=ced78d295d1e0f2b' or one of its dependencies. The system cannot find the file specified.
File name: 'MyCorp.MyDll.Interop, Version=1.2.3.4, Culture=neutral, PublicKey Token=ced78d295d1e0f2b' at MyDllVerify.App..cctor()
I'd like to instruct the C# program to use any COM/C++ dll with version 1.2.anything.
Where can I configure this in the C# project?
I would suggest you to not directly reference to the COM-dll in your C# project. If you do that, at build time there is always a new COM-interop-dll generated. This can lead to a lot of problems.
It would be a better approach to create a COM-interop-dll, store it in your library folder and reference this library in your C# project. Keep this COM-interop-dll as static as possible. If you do it like that, you can replace the used COM-dll as much as you want, as long as your interfaces do not change.
You could try to manipulate this interop assembly and make the version checking for 1.2.* there, if you realy want that (I would not recommend to that, it could cause serious confusion).
Explanation:
The COM-interop-dll is a regular .NET assembly. It works like a wrapper between your C# code and the COM-C++-code you want to use in the C# code.
The COM-interop-dll don't have to be registered for COM. You can install this assembly so many times you like. But it requires that your COM-dll is registered for COM.
Useful tools:
tlbimp
regasm
sn
Nothing is different from the way I documented it in your previous question. You still use <bindingRedirect> to allow the wrong version of the interop assembly to be loaded.
It is fairly unlikely to work in practice, messing with DLL Hell when you use COM is extremely unwise. If you use early binding then COM has no way to verify that you are calling the correct method. Very unlike .NET where the jitter can make checks like these at runtime from the metadata in the assembly. If the C++ programmer did it right then he changed the guids of the types that he changed. Which will make your code bomb with E_NOINTERFACE since you'll use the guid of the old version.
If he didn't, unfortunately way too common, then your program is liable to crash with something nasty like an AccessViolationException. Or worse, it won't crash but will call the completely wrong method.
The failure mode is more benign when you use late binding, you'll get one of the IDispatch errors when the method doesn't exist or if its arguments have changed. Not that this ultimately solves anything, you still have a program that doesn't work. Mess with DLL Hell like this only if you like to live dangerously.

Importing a dll file written in C or C#

I am trying to import a .dll file which is written in C to Microsoft Visual C# Studio 2010?
Any ideas why I keep on getting this error?
Please make sure that the file is accessible and that it is a valid assembly prompt.
You cannot import a reference to a native DLL. Instead you need to use p/invoke to import each function one by one. This can be a rather laborious process if you have a lot of functions so sometimes a C++/CLI wrapper is more convenient.
I suspect you're not using the DllImportAttribute correctly (or at all). See here:
http://msdn.microsoft.com/en-us/library/aa984739(v=vs.71).aspx

Asp.net calling C# layer calling Managed C++ calling Native C++

My project structure is as follow:
ASP.NET calling C# layer calling Managed C++ calling Native C++
(i'm trying to avoid using interop so this is why the managed c++ layer)
I wrote unit test that test the C# layer and it works fine.
When I try to run the asp.net page i'm getting: "Could not load file or assembly..." error.
I figured out that when i copy paste the Native C++ dll to "Temporary ASP.NET Files" (to the corresponding folder) the site works.
It seems that the Managed C++ code can find the Native C++ code only if it resides in the same folder - obviously I can't have my Native dll in the temp files.
Is there a way to set the Native in a global place(doesn't work with System32)?
Thanks for you comments.
It boils down to one option:
It is security issue
i set up the server it self with the code and it runs under the cassini, but when i publish it(to run under iis7) i'm getting "Could not load file or assembly ...."
i'm running IIS7 with ApplicationPoolIdentity , .net 4 Integrated
Thanks a lot,
Pini.
Well technically using Managed C++ in this way is a form of Interop between native / managed code, the commonly used alternatives being COM and P/Invoke. This is purely a terminology thing however, you would get the same issue using P/Invoke.
This blog article Loading C++ Assemblies in ASP.Net might help you out - In short you need to either:
Set the %PATH% environment variable before the Managed C++ assembly attempts to load your native C++ dll.
Use the DllImport attribute to set the dll path (not applicable in your case as you aren't using P/Invoke)
Manually load the C++ dll yourself (e.g. with LoadLibrary) before the Managed C++ assembly attempts to load your native C++ dll.
I suspect that installing your dll to Win SxS would also work, but I don't know enough about how this works to be sure.
You can set your path variable?
You set it by going to the Properties of "My computer"/"Computer (Windows-PauseBreak) and then clicking advanced settings. Click advanced. Environment variables. Modify "Path" under system variables as needed.
I had to flip a bool in the ApplicationPoolIdentity. One of the filed in the properties says "enable 32bit" and that did the trick :) the default is False
My server is 64bit and i build my native with 32bit.

C# app can't find Dll when compiled with /MDd flag

I have a C# application which links to a few c# DLLs which in turn use bindings to call c++ functions in other Dlls.
This all works fine if I compile the c++ Dlls with /MTd but when I use /MDd I get an XMLParseException in my C# app complaining that it can't find any Dlls(it fails to find the first of my Dlls that I use). My best guess is that using this other switch causes it to change the path where it looks for its Dlls, causing it to fail. I used DependencyWalker to have a closer look and the two Dlls it actually fails to find are 'IESHIMS.DLL' and 'WER.DLL'. I can't see my c# Dlls anywhere in the tree in DependecyWalker however. Anyone have any ideas what might be wrong here?
Also, using the non-debug equivalents (/MD and /MT) make no difference. Regardless, I can't use /MT as it causes another bug.
EDIT: I've narrowed the problem down somewhat. When compiled and linked using the VS2010 command prompt, my app works fine, with the VS2008 command prompt it still fails to find the Dll. Does anyone know any differences between these two version of VS which could cause the behaviour I described above?
Thanks in advance,
Are you compiling all the modules against the same run-time libraries? From:
http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.80).aspx
"All modules passed to a given invocation of the linker must have been compiled with the same run-time library compiler option (/MD, /MT, /LD)."

Categories

Resources