locked
DllImport of 32-Bit dlls

    Question

  • Hi guys,

    I am a real newbie on 64-Bit progr. so my question might sound a little stupid.

    I have a VB.NET project which refered to a 32-Bit dll via COM-Interop.

    I migrated the project and the COM invocation does not work anymore. I tried several compiler settings (anyCPU, x86) but nothing helped.

    Then I found in my old C# book a method called DllImport (System.Runtime.InteropServices)

    I declared the dll as follows:

    <DllImport("fcvb.dll", CharSet:=CharSet.Auto)> _

    Function dllBIN2_iv(ByVal price_u As Double, ByVal ex As Double, ByVal d_exp As Double, ByVal d_v As Double, ByVal price As Double, ByVal rate_ann As Double, ByVal acc_rate As Integer, ByVal cost_hldg As Double, ByVal acc_cost_hldg As Integer, ByVal option_type As Integer, ByVal iter As Integer, ByRef return_vlty_imp As Double) As Integer

    End Function

    When calling the Dll I got f... in the middle of the process saying:

    errMsg = "System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
       at Wcr_.NET_2005.Module1.dllBIN2_iv(Double price_u, Double ex, Double d_exp, Double d_v, Double price, Double rate_ann,...

    I am running an AMD64-Bit Opteron with 2GIG of Mem on Windows Server 2003 (64-Bit) Standard.

    Visual Studio 2005 Team Edition for SW Developers and .NET Framework 2.0

     

    Any comments welcome I am open for both a COM wrapper .NET dll or native dll programming whatever is needed.

     

    THNX,

    Martin

    Monday, February 19, 2007 2:00 PM

Answers

  • 

    Hi Will,

    thanks for your reply. I really love this forum you get responses as quick as possible.

    O.K. what I figured out was my old VB.NET (2003 x86) application used a COM object which referred to a 32-Bit dll.

    I wrote a wrapper in VB 6.0 around the 32-Bit dll to make it COM able.

    When I tried to register this COM object on the 64-Bit machine it did dont work. Said the dll was loaded but the entry point was not found.

    Therefore my new VB.NET (2005) program could not instantiate an object of my own created COM class.

    So far so good. Then I thought , oh maybe its better to get rid of this COM wrapper and use the dll with DllImport in my VB.NET (x86 compiler setting) program, but this also fails due to the following reason:

    errMsg = "System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B) at Wcr_.NET_2005.Module1.dllBIN2_iv(Double price_u, Double ex, Double d_exp, Double d_v, Double price, Double rate_ann,...

    Maybe the source of all these problems is the fact that this 32-Bit dll refers to a lib called FCA.lib which I have copied also to the WOW64 and SYSTEM 32 directory.

    I understood that 32-bit compatible dlls should reside in WOW64 and native 64-bit dlls in SYSTEM32 .

    Is that correct?

    Thanx for your support.


    No, the "BadImageFormatException" is thrown on you when the application loads a DLL having incompatible bitness, that is a,  64 bit exe tried to load a 32bit DLL or, a 32 bit exe tried to load a 64 bit DLL.
    In your case, it's probably the first, so please make sure you compile your vb.net exe as 32 bit (X86) and NOT MSIL.
    Note also that you should stay away from SysWow64 and System folders, they are reserved by the system and should not contain user applications/DLL's, user stuff must reside under "program files" or "program files (X86)" in an another private folder.
    So I would suggest you delete all this from the system folders, and move the DLL and the exe to a private folder under "program files (X86)". The lib file has nothing to do with this as it should have beed statically linked when the dll was build.
     
    Willy.
     
     
     
    Tuesday, February 20, 2007 11:36 AM
  • I think (fear) that the Express editions didn't include the ability to change this setting.

    You can however use corflags.exe which is part of the .Net SDK to change the setting on your executable after you've built it.

    http://blogs.msdn.com/joshwil/archive/2005/05/06/415191.aspx

    -josh

    Friday, March 16, 2007 8:46 PM
    Moderator

All replies

  • 

    Hi guys,

    I am a real newbie on 64-Bit progr. so my question might sound a little stupid.

    I have a VB.NET project which refered to a 32-Bit dll via COM-Interop.

    I migrated the project and the COM invocation does not work anymore. I tried several compiler settings (anyCPU, x86) but nothing helped.

    Then I found in my old C# book a method called DllImport (System.Runtime.InteropServices)

    I declared the dll as follows:

    <DllImport("fcvb.dll", CharSet:=CharSet.Auto)> _

    Function dllBIN2_iv(ByVal price_u As Double, ByVal ex As Double, ByVal d_exp As Double, ByVal d_v As Double, ByVal price As Double, ByVal rate_ann As Double, ByVal acc_rate As Integer, ByVal cost_hldg As Double, ByVal acc_cost_hldg As Integer, ByVal option_type As Integer, ByVal iter As Integer, ByRef return_vlty_imp As Double) As Integer

    End Function

    When calling the Dll I got f... in the middle of the process saying:

    errMsg = "System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
    at Wcr_.NET_2005.Module1.dllBIN2_iv(Double price_u, Double ex, Double d_exp, Double d_v, Double price, Double rate_ann,...

    I am running an AMD64-Bit Opteron with 2GIG of Mem on Windows Server 2003 (64-Bit) Standard.

    Visual Studio 2005 Team Edition for SW Developers and .NET Framework 2.0

    Any comments welcome I am open for both a COM wrapper .NET dll or native dll programming whatever is needed.

    THNX,

    Martin


    COM interop hyas nothing to do with DllImport, what you are trying is managed to native code interop, so I really don't know what your DLL exactly is. Anyway, wen using interop, you have to make sure that both the DLL and the consumer of that DLL are both X86 or X64.
    When a VB.NET application calls a function in a X86 DLL, you need to make sure the VB program is compiled for the X86 platform too. The same holds for COM interop, but again, here you don't have DllImport declarations in your program.
     
    Willy.
     
     
     
    Monday, February 19, 2007 8:29 PM
  • Hi Will,

    thanks for your reply. I really love this forum you get responses as quick as possible.

    O.K. what I figured out was my old VB.NET (2003 x86) application used a COM object which referred to a 32-Bit dll.

    I wrote a wrapper in VB 6.0 around the 32-Bit dll to make it COM able.

    When I tried to register this COM object on the 64-Bit machine it did dont work. Said the dll was loaded but the entry point was not found.

    Therefore my new VB.NET (2005) program could not instantiate an object of my own created COM class.

    So far so good. Then I thought , oh maybe its better to get rid of this COM wrapper and use the dll with DllImport in my VB.NET (x86 compiler setting) program, but this also fails due to the following reason:

    errMsg = "System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B) at Wcr_.NET_2005.Module1.dllBIN2_iv(Double price_u, Double ex, Double d_exp, Double d_v, Double price, Double rate_ann,...

     

    Maybe the source of all these problems is the fact that this 32-Bit dll refers to a lib called FCA.lib which I have copied also to the WOW64 and SYSTEM 32 directory.

    I understood that 32-bit compatible dlls should reside in WOW64 and native 64-bit dlls in SYSTEM32 .

    Is that correct?

     

    Thanx for your support.

     

     

    Tuesday, February 20, 2007 8:46 AM
  • 

    Hi Will,

    thanks for your reply. I really love this forum you get responses as quick as possible.

    O.K. what I figured out was my old VB.NET (2003 x86) application used a COM object which referred to a 32-Bit dll.

    I wrote a wrapper in VB 6.0 around the 32-Bit dll to make it COM able.

    When I tried to register this COM object on the 64-Bit machine it did dont work. Said the dll was loaded but the entry point was not found.

    Therefore my new VB.NET (2005) program could not instantiate an object of my own created COM class.

    So far so good. Then I thought , oh maybe its better to get rid of this COM wrapper and use the dll with DllImport in my VB.NET (x86 compiler setting) program, but this also fails due to the following reason:

    errMsg = "System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B) at Wcr_.NET_2005.Module1.dllBIN2_iv(Double price_u, Double ex, Double d_exp, Double d_v, Double price, Double rate_ann,...

    Maybe the source of all these problems is the fact that this 32-Bit dll refers to a lib called FCA.lib which I have copied also to the WOW64 and SYSTEM 32 directory.

    I understood that 32-bit compatible dlls should reside in WOW64 and native 64-bit dlls in SYSTEM32 .

    Is that correct?

    Thanx for your support.


    No, the "BadImageFormatException" is thrown on you when the application loads a DLL having incompatible bitness, that is a,  64 bit exe tried to load a 32bit DLL or, a 32 bit exe tried to load a 64 bit DLL.
    In your case, it's probably the first, so please make sure you compile your vb.net exe as 32 bit (X86) and NOT MSIL.
    Note also that you should stay away from SysWow64 and System folders, they are reserved by the system and should not contain user applications/DLL's, user stuff must reside under "program files" or "program files (X86)" in an another private folder.
    So I would suggest you delete all this from the system folders, and move the DLL and the exe to a private folder under "program files (X86)". The lib file has nothing to do with this as it should have beed statically linked when the dll was build.
     
    Willy.
     
     
     
    Tuesday, February 20, 2007 11:36 AM
  • PERFECT!!!

    I turned of the MSIL setting and now my project runs thru. I can even use the COM dll which I also registred as if nothing had happened, only that I am ten times faster than before. ;)

     

    Thanks so much for your help.

    Cheers,

     

    Martin

    Tuesday, February 20, 2007 1:53 PM
  •  

    I am facing the similar problem. I have developed a web application which is using SAP .net connector to show up data from the sap system. It works fine in 32 bit environment but our production server is 64 bit. when i deployed aht application on server i got following error.

    An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B) at SAP.Connector.Connection.Open() at SAP.Connector.Connection.BeforeCall(SAPClient sapclient) at SAP

    This SAP .net connector internally uses librfc32.dll file whcih i kept in the bin folder of my application as i coulndt register this into SysWow64.

    IIS is running in 64 bit mode which i am seeing as problem are for this.

    Any solution to this?.. To deploy SAP .net connector in 64 bit enivotnment?

    Thanks in Advance.

    Mangesh

    Saturday, March 03, 2007 8:51 AM
  • Hi !

    I have the same problem as you.

    How did u switch off the MSIL setting. I just cant find it in Visual Basic 2005 Express Edition.

    Cheers,


    Lukas
    Monday, March 12, 2007 4:56 PM
  • Go into the options, select 'Show all Settings' - then you see a treeview, select the entry 'Projects and Solutions' and under 'General' you can activate 'Show advanced build configuration'. Say OK. Then you should see in the toolbar two comboboxes for changing the build configuration (debug/release) and the target plattform (any cpu, x86 und x64). If you don't see them in the combobox, go into the configuration manager where you should set the option.
    Monday, March 12, 2007 9:05 PM
  • Hi Mangesh,

    1st question do you work @ SAP? If yes you should know. I have  no clue about SAP connector but if I treat it let's say as an external dll only then you should be able to compile your project (VB.NET, ASP.NET) in 32-Bit mode by setting the CPU settings under Project refs. (Advanced options dialog) to 32-Bit.

    Be care full to set both debug/release config.

    Hope that helped!

     

    Tuesday, March 13, 2007 8:48 AM
  • I think (fear) that the Express editions didn't include the ability to change this setting.

    You can however use corflags.exe which is part of the .Net SDK to change the setting on your executable after you've built it.

    http://blogs.msdn.com/joshwil/archive/2005/05/06/415191.aspx

    -josh

    Friday, March 16, 2007 8:46 PM
    Moderator
  • martin_eifert

    You mentioned about turning off the MSIL settings.

    Can you please tell me where can i find this setting?

    I am using Visual Studios 2005 Professional Edition

    Regards,

    Mangesh

    Wednesday, March 21, 2007 8:00 AM
  • A 64 bit process cannot load a 32 bit DLL either through DllImport or COM. However a 64 bit process CAN talk to a 32 bit exe COM server. If you can't switch to 32 bit mode for your client, you might consider writing a COM wrapper EXE. I have no idea if VB can do this. Delphi does it by default, I think.
    Wednesday, March 21, 2007 7:56 PM
  • Thanks Ralf ... this fixed my problem.

    Much obliged.
    Monday, March 16, 2009 8:39 PM
  • Para que funcione SAP Connector en un ambiente de 64 bits seguir los siguientes pasos:

    1.- Dirigirse a las propiedades del proyecto que esten desarrollando (usumimos que ya hemos generado la conexión a SAP con .NET 2003 con Framework 1.1)
    2.- Luego en la sección "Build" de nuestro proyecto ubicamos la opción "Platform target" y escogemos "x86"
    3.- Asumimos que contamos con las siguientes dll traidas desde la carpeta c:\Windows\System32 de nuestro ambiente de 32bits: librfc32.dll, msvcp71.dll, msvcr71.dll, SAP.Connector.dll y SAP.Conector.Rfc.dll

    4.- Copiar el archivo librfc32.dll hacia la siguiente ruta C:\WINDOWS\system
    5.- Copiar el archivo msvcp71.dll hacia la siguiente ruta C:\WINDOWS\system32
    6.- Copiar los archivos msvcp71.dll y msvcr71.dll hacia la siguiente ruta C:\WINDOWS\SysWOW64
    7.- Arrastrar los archivos SAP.Connector.dll y SAP.Conector.Rfc.dll hacia la siguiente ruta C:\WINDOWS\assembly

    Si fuera necesario descarguense antes el "Microsoft Visual C++ 2008 SP1 Redistributable Package (x64)" desde la pagina de microsoft, este archivo contiene dlls necesarias para un ambiente donde no se tiene instalado VS 2008.

    Con eso me funcionó sin ningun problema.

    Compartanlo!!!
    Friday, January 15, 2010 3:31 PM
  • If you try to run 32-bit applications on IIS7 (and/or 64-bit OS machine) you will get the same error. So, from the IIS7  right click on the applications' application pool and go to "advanced settings" and change "Enable 32-Bit Applications" to "TRUE".

    Restart your Website and it should work. 


    Cheers,

    Kalyan Revadi

    • Edited by Kalyan Revadi Thursday, January 06, 2011 8:03 PM more info
    • Proposed as answer by kennyshu Friday, February 03, 2012 7:16 AM
    Thursday, January 06, 2011 7:58 PM
  • I think (fear) that the Express editions didn't include the ability to change this setting.

    You can however use corflags.exe which is part of the .Net SDK to change the setting on your executable after you've built it.

    http://blogs.msdn.com/joshwil/archive/2005/05/06/415191.aspx

    -josh

    Josh,

    Thanks for the information.  I am using Visual C# Express, and I don't believe there is any such switch. So, am I correct in saying that my 64-bit system is running a MSIL program as 64-bit instead of 32-bit, and then when I use DllImport for a 32-bit .dll, it complains with a BadImageFormatException (inner) + TypeInitializationException (outer), since 32-bit isn't compatible with the 64-bit loader? And the only way around this is to tell the compiler to stop making generic MSIL code, and instead make 32-bit code, so that way a 64-bit system will be forced to run it at 32-bit? And such a switch is not available in the Express editions?

    This would follow with what I am seeing, since I have old 32-bit apps compiled in VC# 2005 Express running on my new Windows Vista 64-bit (yes new, don't have Win7 yet), and suddenly the programs are crashing on start. I have loaded the code into VC# 2008 Express on the new 64-bit system, and I can see the errors are the exceptions I mentioned above.

    Further, I cannot find corsflag.exe that you mention as an after-thought .exe-hacking tool to fix the switch that the VC# Express does not provide. I have VC# 2008, 2010 and C++ 2010 all installed, and I cannot find corflags*.* anywhere using both CMD's DIR /s search and Windows search (which I never trust). Where can I obtain this tool?

    Thank you GREATLY for your help and time. It is invaluable!

     


    Jason Doucette / Xona Games
    Thursday, March 17, 2011 3:49 AM
  • Ok it turns out that VC# 2008 Express does have the option. You just have to make another build configuration, and one of the options within this is "x86". Compiling with this option and running it on Windows Vista 64-bit will run my .exe just fine, and doesn't crash when it DllImport's the 32-bit .DLL file.

    In any case, thank you GREATLY for your help.


    Jason Doucette / Xona Games
    Thursday, March 17, 2011 5:39 AM
  • It turns out that VC# 2008 Express indeed does have the option. 

    Very good answer how to turn x86 build options can be found here:

    http://stackoverflow.com/questions/1381968/setting-32-bit-x86-build-target-in-visual-c-sharp-2008-express-edition

    This solved my problem on x64 PC!

    Wednesday, February 22, 2012 8:25 AM