0
votes

I have an unmanaged VC++ project that I can build for both x86 and x64 targets. It is being consumed by a .NET program that is compiled for Any CPU. This is on VS2010, but I had the same issue when the solution was built with VS2008 and vcbuild.

Here is the build command in my build script:

msbuild .\Project.vcxproj /t:Build /p:PlatformToolset=v100 /p:Configuration=Release /p:Platform=%platform%

If build on an x86 machine, with %platform%=Win32, everything builds and executes fine

If build on an x64 machine, with %platform%=x64, everything builds and executes fine.

However, if I build on an x64 machine, with %platform%=Win32, it builds successfully with no errors. But when I copy those supposedly-x86 binaries to an x86 machine, they cause the following error:

System.Runtime.InteropServices.SEHException was caught
  Message=External component has thrown an exception.

Tracing that error back to the C++ dll, it failed on this line:

if ( FAILED( g_Connection.CreateInstance( _T("ADODB.Connection") ) ) )
    ThrowException(_T("Cannot create connection."));

I've gone through my .vcxproj file looking for issues but everything appears correct. There are no imported property files or custom build tasks or anything like that.

This is causing issues because we are trying to use a single x64 build server to create builds for both platforms. Our current workaround involves pre-building the C++ dll on two different machines.

1
Could you post the runtime error you're getting when attempting to run on an x86 machine?Jacob
"they cannot be loaded", apparently.Hans Passant
After a closer look, it's throwing a SEHException so it looks like the C++ dll is being loaded correctly but threw an exception creating an object. I think this is a dependency issue rather than an issue with the C++ dll itself.Dave Bauman

1 Answers

0
votes

I traced the issue back to this line cleverly hidden in one of the header files:

#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","EndOfFile")

That will always link the x86 dll with the x64 version of msdado15.dll, when building on a x64 machine--regardless of the build target platform.

I solved it by copying the ADO files for both platforms into my project directory, and updating the project and header:

#import "msado15.dll" no_namespace rename("EOF","EndOfFile")

.vcxproj file: (relevent lines shown only)

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <AdditionalIncludeDirectories>.\ado\Win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <AdditionalIncludeDirectories>.\ado\x64;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
</ItemDefinitionGroup>