Visual Studio 2010 64-bit COM Interop Issue - com

I am trying to add a VC6 COM DLL to our VS2010RC C# solution. The DLL was compiled with the VC6 tools to create an x86 version and was compiled with the VC7 Cross-platform tools to generate a VC7 DLL.
The x86 version of the assembly works fine as long as the consuming C# project's platform is set to x86. It doesn't matter whether the x64 or the x86 version of the DLL is actually registered. It works with both. If the platform is set to 'Any CPU' I receive a BadImageFormatException on the load of the Interop.<name>.dll.
As for the x64 version, I cannot even get the project to build. I receive the tlbimp error:
TlbImp : error TI0000: A single valid machine type compatible with the
input type library must be specified.
Has anyone seen this issue?
EDIT:
I've done a lot more digging into this issue and think this may be a Visual Studio bug. I have a clean solution. I bring in my COM assembly with language agnostic 'Any CPU' selected. The process architecture of the resulting Interop DLL is x86 rather than MSIL.
May have to make the Interop by hand for now to get this to work.
If anyone has another suggestion let me know.

This issue can be resolved by opening the CSProj file and adding the following node to any of the '(Configuration)|Any CPU' nodes that are missing it:
<PlatformTarget>AnyCPU</PlatformTarget>
If this node is not present TlbImp will default to x86 and cause issues.

Related

Statically compile SQLite into a VB.Net application?

System.Data.SQLite (SDS) is apparently the most popular way to use SQLite from a .Net application.
I was wondering if
SDS requires shipping the SQLite DLL in addition, or if SDS includes
the SQLite source code, and
SDS can be statically compiled into a
VB.Net application of it can only be shipped as a DLL?
Thank you.
To expand on my comment, SDS is a .net wrapper for unmanaged code, so you will need to ship your release code with a copy of the DLL.
As Steve mentions, there are 32 and 64bit versions of the DLL, and as i discovered after much frustration, you must have the corresponding visual c++ runtime installed on the target machine, so if you deploy the 32bit version onto a 64bit machine, it will need the 32bit c++ runtime environment installed.
An alternative that i am currently looking into but havent had time to test is csharpe-sqlite, a pure .net implementation:
http://code.google.com/p/csharp-sqlite/
Coded in c# as the name suggests, but of course usable in any .net language including vb.net
Actually it's quite easy to compile System.Data.SQLite.dll to the does not require C++ runtime. For example if you download source code and follow the build procedures you'll find statically linked (no C/C++ runtime required) copy of System.Data.SQLite.dll in the following path:
<your-src-root>\bin\<2008 or 2010>\<Win32 or x64>\ReleaseStatic
For example if your source is in C:\Work\sqlite-netFx-source-1.0.80.0 then statically linked binary for Win32 and .NET 3.5 (VS 2008) will be located in:
C:\Work\sqlite-netFx-source-1.0.80.0\bin\2008\Win32\ReleaseStatic
Furthermore since System.Data.SQLite.dll is a mixed-mode assembly consisting of a managed .netmodule and native .obj file linked together using link.exe, it is possible to build your app as a .netmodule as well and link it together with SQLite into a single mixed mode assembly.
The resulting assembly will still be either Win32 or x64, however since almost all x64 machines will have no problem running Win32 code you can just settle on Win32 as long as:
Your app is an .exe or a .dll the is always loaded into a Win32 process, and
You don't use any of x64 specific advantages such as larger address space or using unmanaged code available only in x64

Calling an x86 dll from a VS 2010/DotNet 4.0 x86 targeted app

I'm getting an 'AccessViolationException' 'Attempted to read or write protected memory' when calling a method in an x86 dll when running on an x64 platform (Windows 7). Everything works great on x86 platforms.
I've read many, many posts about similar problems but haven't been able to get my code to work.
I'm in the process of trying to make our old x86 app work happily on Windows 7 (x64) and Server 2008 R2 (x64). The app is an assortment of VB6 , VB.Net, C#, MicroFocus COBOL and C++. (We couldn't think of any other languages to throw in at the time). The DotNet code was originally written in Visual Studio 2003 for DotNet 1.1. I've ported the code up to Visual Studio 2010 and DotNet 4.0. I've set the target for all the projects to x86. When I call into un-managed 32 bit dll's I get the above error.
Our InstallShield setup routine is installing the x86 dll's into C:\Windows\sysWOW64 instead of C:\Windows\System32. This behavior seems correct. The dll's are some COBOL object code and runtime components linked together into a 'C Style' dll. I don't think the problem has to do with COBOL or the linking process as I also ported up a sample app from Code Project with a VB.Net WinForms app that calls a simple C++ dll, all targeted to x86. I get the same error there. I've also tried building a C++ command line app to call the dll. The Load Library succeeds. GetProcAddress succeeds. Calling the function pointer for the particular method fails. Our VB6 apps can call the dll's just fine when running on Windows 7 x64. I've also tried turning off UAC and setting the requestedExecutionLevel in the manifest to the highestAvailable. I've tried running as administrator.
Seems like this should work, but not sure what to try next. Any ideas?
On x64 .net programs will be run as 64-bit programs and cannot call 32bit-dlls.
Try compiling the application with target x86 instead of "Any Target". You can also force the
target of the built .exe with the .Net CorFlags.exe utility to run in 32bit-mode.
Of course your program will then run in the 32bit environment, especially it will only have a maximum of 2gb of RAM.
Good news,
We investigated DEP as a possible cause of the problem as we saw that even our VB6 code will fail when DEP is turned on. We noticed that the VB.Net code was failing in the same way as VB6 when DEP was on. Apparently our COBOL dll's do something that DEP isn't happy with. Unfortunately the DotNet assemblies don't seem to respect the operating system DEP setting, so you have to turn off DEP with using editbin.exe:
editbin.exe /nxnocompat:no
I still have to test it on our full application, but it looks like we have a solution!

Compile dll as earlier build

When I try to run the dll I compiled in Visual Studio 2010, I get the following message: This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded. I'm guessing this means that I am a too recent version of Visual Studio. Is there a way I can build the dll as an earlier version?
All assemblies in your final solution, be they dlls or exes, in different solutions or in the same one, must target the same version of the CLR. You can ensure they do by configuring targeting in your 2010 solution.
Most likely you're targeting 4.0 in your dll's project. Crank it back to 3.5 or earlier and see if that fixes the problem.

.lib and .dll Backward Compatibility

I currently have a VS6 unmanaged C library that I deliver as either a .lib or .dll. I want to upgrade to VS2010 but I still have users that are in VS6, VS2005, and VS2008.
Can a .lib or .dll built in VS2010 be used in VS6, VS2005, or VS2008?
Thanks!
It depends on the runtime used to build the libraries. I would typically run into this problem when upgrading solutions from VS2005 to VS2008. The default runtime libraries are different from edition to edition.
When you're building the .lib and .dll, those files are getting linked against those editions of the runtime. Problems will typically be found when you're debugging the program between different VS editions or running it on a non-developer machine when assemblies built with different runtimes attempt to pass information across boundaries. See http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx for details.
I know this is an old post but if anyone else comes across it this may be useful, upgrading from vc6 to vs2010 is a nightmare, but there is an alternative. You can upgrade to VS2010 environment while still using vc6 compiler. the tool you need is Daffodil and can be found here http://daffodil.codeplex.com/
This was our solution because the VS2010 environment is way more productive.

Sharing a mex64 file across computers

I have a mex64 dll compiled on my machine. I used Matlab 2009b with VS2008 Pro to compile the dll. The dll works fine on my Matlab installation.
I want a colleague to use the dll so I sent it to him and he gets the following error message when trying to use the dll:
??? Invalid MEX-file 'filename.mexw64': The specified module could not be found.
My current assumption is that this is caused because he uses an older Matlab version or missing a dll that I have. I ran dependency checker and asked him to check that he has all the listed dlls.
I am still waiting for him to confirm his Matlab version.
What other reasons can cause this and can the Matlab version make a difference? (I mean R2009a when I have R2009B and not a huge version diff)
The other person has Matlab R2009a. Shouldn't the mex just work if I compile it on my computer and deliver it to him?
Does this only leave a missing dependent dll?
The issue is strange, but I can confirm it exists.
Using pre-built libraries for matlab that are correctly installed and in the path, I sometimes get the same error. If I type in the function name at the command-line, the function is visible and will auto-complete. However, the function will not initialize until I 'cd' into the directory with the .mexw64 library file.
>> AndorInitialize('')
Invalid MEX-file 'C:\Program
Files\MATLAB\R2011b\toolbox\andor\AndorInitialize.mexw64': The
specified module could not be found.
>> path
MATLABPATH
C:\Program Files\MATLAB\R2011b\toolbox\andor
C:\Program Files\MATLAB\R2011b\toolbox\andor\camera files
C:\Program Files\MATLAB\R2011b\toolbox\andor\m files
... etc
It turns out this is due to missing dependencies, which shouldn't be missing. To resolve the issue, use dependency walker (free, lightweight) to identify what's missing. The mathworks explains this.
http://www.mathworks.com/support/solutions/en/data/1-2RQL4L/
In my case, two DLL's weren't showing up properly, even though they were on my system and in the path. I copied the DLL's into the windows/system32 folder and the library functions now work correctly. What's particularly strange is that the same library worked on my computer a few days ago (prior to the moving the DLL's).
In general, MEX files should work across different versions of Matlab; in particular, they should be forward-compatible. You're right; sounds like a dll problem.
If you built it with Visual Studio, it may be linked to the Visual C++ Runtime. This is a set of libraries that is not installed on Windows by default. The "redistributable" for it can be downloaded here; having your coworker install that could resolve the problem. If that doesn't work, you can use Dependency Walker to check for other unsatisfied DLL dependencies.
Normally, configuring Matlab's "mex -setup" to use the Lcc compiler that's distributed with Matlab could be a way around this, but it's not supported for 64-bit Windows AFAIK.
Also, are you sure he has the 64-bit version of Windows?
Another possible source of the problem could be that you compiled in debug mode. The Visual C++ redistributables only support release mode.
The Dll was a wrapper for MySql access. We ended up using Matlab's ODBC and the MySql Connector.