none
Setup IPC mechanism(32-bit to 64-bit) RRS feed

  • Question

  • I researched this here and elsewhere for some time and realize that https://www.scribd.com/document/56629579/64-Bit-Insider-Volume-1-Issue-7 describes some options. I have a 32-bit DLL and no source code. And I couldn't quite understand the IPC mechanism to setup to make this work.

    Here is my attempt to do it without IPC.

    Initially I tried this in my 64-bit C# code. I thought I could get a reference to the DLL's pointer but I got null.

    static class NativeMethods
        {
        [System.Runtime.InteropServices.DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string dllToLoad);
    
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    
        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);
    
    }

    I also thought that this could work. It didn't.

            [DllImport("C:\\emulator\\pcshll32.dll")]
        public static extern UInt32 hllapi(out UInt32 Func, StringBuilder Data, out UInt32 Length, out UInt32 RetC);

    It seems that there is a process to setup this IPC mechanism. How can I go about doing that ?


    Saturday, November 4, 2017 5:05 PM

All replies

  • The referenced article discusses 64/32 bit IPC in the context of COM (Component Object Model).  Does the 32 bit dll that you wish to use contain code to register and instantiate COM objects?
    Saturday, November 4, 2017 5:20 PM
  • I see "hllapi". I assume that is IBM's HLLAPI as described in IBM Knowledge Center - EHLLAPI Functions, which is old technology that uses a (screen-scraping) protocol based on IBM's dumb 3270 terminals for communication. Also see What is HLLAPI? Webopedia Definition, but there are many other relevant sources of information if anyone needs more.

    There is probably something that allows you to use .Net's WCF with HLLAPI and if you can do that then you are more likely to be successful.

    Assuming it is not IBM's HLLAPI or you are unable to use WCF, can you tell us if you have access to the DLL's project (source code)? If not then the question is not about IPC mechanisms but about use of the specific DLL. Another indication that it is not IPC is that you are using LoadLibrary which will load the DLL into the same process so the communication is not inter-process; not IPC. The communication is intra-process, correct?

    I donated a book about using IBM's SNA and TCP/IP to the Los Angeles Public Library but it might help your situation. There are many resources available if you are attempting to communicate using IBM's communication technology.



    Sam Hobbs
    SimpleSamples.Info


    Saturday, November 4, 2017 6:37 PM
  • It is IBM's hllapi.

    My attempts are probably not right. There is no source code that I know of.

    I see two options.

    1. Use the hllapi 32-bit DLL and figure out how to communicate with it from my 64-bit process. At this time I am interested in this.

    2. Use Java and remove hllapi DLL altogether. I've seen some telnet connections being made using pure Java. I may attempt this later. I assume telnet connections to the 3270 emulator can scrape the text.

    Thanks,

    Mohan

    Sunday, November 5, 2017 2:10 PM
  • 1. Use the hllapi 32-bit DLL and figure out how to communicate with it from my 64-bit process. At this time I am interested in this.
    You could create a 32 bit out of process COM server that wraps the hllapi dll.  The COM server would expose methods with prototypes that duplicate those used by the hllapi dll and function as a pass-through.  It is possible that you will also need to create and register both 32 bit and 64 bit proxy dlls for COM to use when marshaling calls across the 64 bit/32 bit boundary.  Your 64 bit code would then be able to instantiate the 32 bit COM server and use its methods to access the 32 bit hllapi dll.

    • Edited by RLWA32 Sunday, November 5, 2017 7:59 PM
    • Proposed as answer by 宝宝徐 Monday, November 6, 2017 8:32 AM
    Sunday, November 5, 2017 7:59 PM
  • If it were me I would search for resources. IBM Knowledge Center - Introduction to IBM Standard EHLLAPI, IBM Enhanced EHLLAPI and WinHLLAPI Programming seems to be relevant IBM documentation except it uses C++. Using EHLLAPI in C# - CodeProject seems to be an article describing how to use C#. Note that it would help to find the HAPI_C.H file; you need to understand C to understand it but you might need to use that file to get details.

    If there is any way you can make your application 32-bit then you should do that. Then one possibility would be to get some code written in C++ that provides a .Net Class Library. Or just use DllImport as you are already doing.

    As for using Java to do the Telnet, you should be able to do Telnet from C#. I do find many articles about that.



    Sam Hobbs
    SimpleSamples.Info

    • Proposed as answer by 宝宝徐 Monday, November 6, 2017 6:09 AM
    Sunday, November 5, 2017 9:50 PM
  • DllImport didn't work when I tried. The exception is BadImageFormatException which denotes the mismatch between the 64-bit process and the 32-bit DLL.

    Update : No. I can't make it 32-bit.

    Thanks,

    Mohan


    Thursday, November 9, 2017 1:53 PM
  • Hello,

                Could you give some details ? I am not a .NET dev. but can code basic stuff. Mainly I was loading my

    C# DLL from Java using JNI4NET.

    But don't think this is relevant. It is the COM procedure that could help here.

    Thanks,

    Mohan


    Thursday, November 9, 2017 3:40 PM
  • Hello,

                Could you give some details ? I am not a .NET dev. but can code basic stuff. Mainly I was loading my

    C# DLL from Java using JNI4NET.

    But don't think this is relevant. It is the COM procedure that could help here.


    In my earlier response I described, in general terms, how to go about achieving 64/32 bit interoperability using COM.  You say you are not a .NET dev.  Do you have experience with COM?  With C/C++?
    Thursday, November 9, 2017 4:00 PM
  • DllImport didn't work when I tried. The exception is BadImageFormatException which denotes the mismatch between the 64-bit process and the 32-bit DLL.

    I don't understand how it could possibly mean there is a mismatch. It means the DLL is not what you say it is.


    Sam Hobbs
    SimpleSamples.Info

    Thursday, November 9, 2017 6:51 PM
  • C# DLL from Java using JNI4NET.

    Then COM is not relevant. JNI4NET allows you to use Java from C# as if the Java is .Net.

    Did you generate the proxy using Generating Proxies? Are you sure you did that correctly and you are using it as documented?



    Sam Hobbs
    SimpleSamples.Info


    • Edited by Simple Samples Thursday, November 9, 2017 7:03 PM merging posts
    Thursday, November 9, 2017 6:58 PM
  • DllImport didn't work when I tried. The exception is BadImageFormatException which denotes the mismatch between the 64-bit process and the 32-bit DLL.

    I don't understand how it could possibly mean there is a mismatch. It means the DLL is not what you say it is

    One of the reasons that BadImageFormatException can result is a 64/32 bit mismatch.  The OP has clearly described an attempt to use PInvoke from 64 bit code to load a 32 bit dll.

    Thursday, November 9, 2017 7:33 PM
  • One of the reasons that BadImageFormatException can result is a 64/32 bit mismatch.  The OP has clearly described an attempt to use PInvoke from 64 bit code to load a 32 bit dll.

    Sure, one of the reasons. But Radhakrishnan Mohan seems to be assuming it is the only possibility. If it is not the cause of the error then it is wrong to assume it is.


    Sam Hobbs
    SimpleSamples.Info

    Thursday, November 9, 2017 8:09 PM
  • Given the circumstances a 64/32 bit mismatch would seem to be the likely cause of the error.  It's not exactly an unfounded assumption.  I'm sure you agree that attempting PInvoke from a 64 bit process to use a 32 bit dll can only result in an error,

    • Edited by RLWA32 Thursday, November 9, 2017 8:35 PM
    Thursday, November 9, 2017 8:33 PM
  • We are going in circles. We are repeating what has already been said. Instead of speculating, we need a response from Radhakrishnan Mohan.


    Sam Hobbs
    SimpleSamples.Info

    Thursday, November 9, 2017 9:09 PM
  • We are going in circles. We are repeating what has already been said. Instead of speculating, we need a response from Radhakrishnan Mohan.

    The OP has already said that attempting PInvoke from 64 bit code with a 32 bit dll fails.  What more is there? 


    From MSDN regarding BadImageFormatException -

    If your application uses 32-bit components, make sure that it always runs as a 32-bit application. 

    If the Platform target property for your application project is set to AnyCPU, the compiled application can be run in either 64-bit or 32-bit mode. When it runs as a 64-bit application, the just-in-time (JIT) compiler produces 64-bit native code. If the application depends on a 32-bit managed or unmanaged component, that component will fail to load in 64-bit mode. To correct this problem, set the project's Platform target property to x86 and recompile.

    Make sure that you are not using a component that was created with a different version of the .NET Framework.

    This exception is thrown when an application or component that was developed by using the .NET Framework 1.0 or the .NET Framework 1.1 attempts to load an assembly that was developed by using the .NET Framework 2.0 SP1 or later, or when an application that was developed by using the .NET Framework 2.0 SP1 or the .NET Framework 3.5 attempts to load an assembly that was developed by using the .NET Framework 4. The BadImageFormatException exception may be reported as a compile-time error, or the exception may be thrown at run time. See the BadImageFormatException class for an example.

    Make sure that the file image is a valid managed assembly or module.

    This exception is thrown when an unmanaged dynamic link library or executable is passed to the Load method for loading.

    • Edited by RLWA32 Thursday, November 9, 2017 9:51 PM Added MSDN info
    Thursday, November 9, 2017 9:31 PM
  • Hi Sam,

                   I think these two issues are not related to each other. The flow is this.

    1. Java(64-bt) loads my 64-bit C# DLL using JNI4NET. No problem here. Works fine. Able to call.

    2. 64-bit C# DLL attempts to load my 32-bit hllapi DLL. Problem is here.

    3. I get the error because there is no proper IPC. Problem is here. But if this is wrongly assumed then I would need some help with this.

    I am using Java and that could cause further confusion. Apology. But that is the need here.

    Thanks,

    Mohan




    Saturday, November 11, 2017 6:00 AM
  • Hi Sam,

                   I think these two issues are not related to each other. The flow is this.

    1. Java(64-bt) loads my 64-bit C# DLL using JNI4NET. No problem here. Works fine. Able to call.

    2. 64-bit C# DLL attempts to load my 32-bit hllapi DLL. Problem is here.

    3. I get the error because there is no proper IPC. Problem is here. But if this is wrongly assumed then I would need some help with this.

    I am using Java and that could cause further confusion. Apology. But that is the need here.




    It appears you have properly identified the issue as the known inability to directly use a 32 bit dll in a 64 bit process.

    Am I correct in assuming that you have no prior experience with COM?

    Saturday, November 11, 2017 10:17 AM
  • I think that the "file image is a valid managed assembly or module" could be relevant. I am confused about what is what here. If not that then "different version of the .NET Framework" might be relevant.

    As best as I understand things, PInvoke is not relevant here. If so then the documentation and samples are critical.



    Sam Hobbs
    SimpleSamples.Info

    Saturday, November 11, 2017 8:50 PM
  •  I haven't used COM. But I can try. I use VS community edition.

    Mohan

    Sunday, November 12, 2017 2:35 AM
  • Either you must use COM or you must not use it. It depends on the way the software is designed. You are not clear about how the software is designed to be interfaced with.

    See IBM manual SC31-8478; probably SC31-8478-09 where the suffix "09" is the version (I learned about the version suffix in about 1971); the version I am looking at is Tenth Edition (July 2006). The name is "Personal Communications for Windows, Version 5.9 Emulator Programming". It is the relevant documentation. see IBM Knowledge Center - Emulator Programming but that is probably not the best place to download it from.

    When I was in High School I worked as a janitor and I had to pay $30 for IBM manuals but now they are available for free.

    Page 6 has "Languages" and it essentially says you must use Pinvoke (DllImport). I don't know how you are using JNI4NET but it seems irrelevant here. COM is also irrelevant. You can't use COM for this. Page 9 has "Compiling and Linking". It says that PCSHLL32.DLL is the "IBM Enhanced (32-bit)" interface. It also shows C code for using LoadLibrary and GetProcAddress to link to the DLL.

    So we now know for sure that it is a 32-bit DLL so you must Pinvoke (DllImport) with it. Either that or get a C or C++ programmer to write something that can be used from .Net. If you post another question here then you must say that you are attempting to use a 32-bit native DLL. Don't say IPC; you are not using IPC nor need to.

    You did not show the code that calls LoadLibrary and GetProcAddress; are you sure you called them?



    Sam Hobbs
    SimpleSamples.Info

    Sunday, November 12, 2017 4:14 AM
  • using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Reflection;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    
    namespace EmulatorLibrary
    {
    
        static class NativeMethods
        {
            [System.Runtime.InteropServices.DllImport("kernel32.dll")]
            public static extern IntPtr LoadLibrary(string dllToLoad);
    
            [DllImport("kernel32.dll")]
            public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    
            [DllImport("kernel32.dll")]
            public static extern bool FreeLibrary(IntPtr hModule);
    
        }
        public class EmulatorDelegate
        {
    
            [DllImport("C:\\emulator\\pcshll32.dll")]
            public static extern UInt32 hllapi(out UInt32 Func, StringBuilder Data, out UInt32 Length, out UInt32 RetC);
    
            public delegate UInt32 dhllapi(out UInt32 Func, StringBuilder Data, out UInt32 Length, out UInt32 RetC);
    
    
            [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool SymInitialize(IntPtr hProcess, string UserSearchPath, [MarshalAs(UnmanagedType.Bool)]bool fInvadeProcess);
    
            [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool SymCleanup(IntPtr hProcess);
    
            [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern ulong SymLoadModuleEx(IntPtr hProcess, IntPtr hFile,
                    string ImageName, string ModuleName, long BaseOfDll, int DllSize, IntPtr Data, int Flags);
    
            [DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool SymEnumerateSymbols64(IntPtr hProcess,
                ulong BaseOfDll, SymEnumerateSymbolsProc64 EnumSymbolsCallback, IntPtr UserContext);
    
            public delegate bool SymEnumerateSymbolsProc64(string SymbolName,
                                                            ulong SymbolAddress,
                                                            uint SymbolSize,
                                                            IntPtr UserContext);
    
     
            public static bool EnumSyms(string name, ulong address, uint size, IntPtr context)
            {
                System.Diagnostics.Debug.WriteLine(name);
                return true;
            }
    
            public String test()
            {
                StringBuilder Data = new StringBuilder(4);
                Data.Append(1); //sessionID);
                UInt32 rc = 0;
                UInt32 f = 1; // HA_CONNECT_PS;
                UInt32 l = 4;
                EmulatorDelegate.hllapi(out f, Data, out l, out rc);
                return "Test with function pointer";
            }
    
            public static void Connect(IntPtr pointerAddressOfFunctionToCall)
            {
                StringBuilder Data = new StringBuilder(4);
                Data.Append(1); //sessionID);
                UInt32 rc = 0;
                UInt32 f = 1; // HA_CONNECT_PS;
                UInt32 l = 4;
                //dhllapi result = (dhllapi)Marshal.GetDelegateForFunctionPointer(
                                                                    //pointerAddressOfFunctionToCall,
                                                                    //typeof(EmulatorDelegate.dhllapi));
            }
    
            static void Main(string[] args)
            {
                debug();
                System.Diagnostics.Debug.WriteLine(new EmulatorDelegate().test());
            }
    
    
            /*
             *     Just debug loaded DLL's symbol visually
             */
            static void debug()
            {
    
                    IntPtr hCurrentProcess = Process.GetCurrentProcess().Handle;
    
                    ulong baseOfDll;
                    bool status;
    
                    // Initialize sym.
                    // Please read the remarks on MSDN for the hProcess
                    // parameter.
                    status = SymInitialize(hCurrentProcess, null, false);
    
                    if (status == false)
                    {
                        System.Diagnostics.Debug.WriteLine("Failed to initialize sym.");
                        return;
                    }
    
                    // Load dll.
                    baseOfDll = SymLoadModuleEx(hCurrentProcess,
                                                IntPtr.Zero,
                                                @"C:\\emulator\\pcshll32.dll",
                                                null,
                                                0,
                                                0,
                                                IntPtr.Zero,
                                                0);
    
                    if (baseOfDll == 0)
                    {
                        System.Diagnostics.Debug.WriteLine("Failed to load module.");
                        SymCleanup(hCurrentProcess);
                        return;
                    }
    
                    // Enumerate symbols. For every symbol the 
                    // callback method EnumSyms is called.
                    if (SymEnumerateSymbols64(hCurrentProcess,
                        baseOfDll, EnumSyms, IntPtr.Zero) == false)
                    {
                        System.Diagnostics.Debug.WriteLine("Failed to enum symbols.");
                    }
    
                    // Cleanup.
                    SymCleanup(hCurrentProcess);
    
                }
        }
    
    }

    That is the entire code. Parts of the code is used to just debug. 'test' is the actual function needed. If the solution is set to 'Ány CPU' it loads. No error. Now I am trying to debug the C# code directly. No Java.

    But if it is set to 'x64' I see this.

    System.BadImageFormatException: 'An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)'

    'Any CPU' DLL didn't work when I invoke from 64-bit Java. Exception is same in Java.



    Sunday, November 12, 2017 7:58 AM
  • Your response is not clear.

    Is your process running as a 64 bit or 32 bit process?

    When the settings indicate x64 instead of AnyCPU exactly what causes the BadImageFormatException?

    Has the C# dll been successfully loaded into a 64 bit process?

    Does the exception occur when the C# dll attempts to call a function from the hllapi dll?



    • Edited by RLWA32 Sunday, November 12, 2017 12:02 PM
    Sunday, November 12, 2017 11:50 AM
  • >> Does the exception occur when the C# dll attempts to call a function from the hllapi dll?

    Yes. The 'test' function.

    Sunday, November 12, 2017 12:37 PM
  • >> Does the exception occur when the C# dll attempts to call a function from the hllapi dll?

    Yes. The 'test' function.

    And this happens from within a 64 bit process?

    COM is relevant as a solution to the 64/32 bit interoperability problem.

    • Edited by RLWA32 Sunday, November 12, 2017 12:52 PM
    Sunday, November 12, 2017 12:50 PM
  • See my posts in the Visual C++ forum at LNK1112 Error: use of x86 library in x64 configuration in which I demonstrate how a 64 bit process can invoke 32 bit code by using COM.

    Sunday, November 12, 2017 1:12 PM
  •  I have reached a logical conclusion. :-) I could try your solution. I have to manipulate the registry for this ?

    Any basic instructions ?

    Mohan

    Sunday, November 26, 2017 1:06 PM
  •  I have reached a logical conclusion. :-) I could try your solution. I have to manipulate the registry for this ?

    Any basic instructions ?

    Mohan

    If by this you mean you would like to pursue using COM for 64/32 bit IPC there is more involved than "manipulating the registry".  As I said on 11/5/2017 -

    "You could create a 32 bit out of process COM server that wraps the hllapi dll.  The COM server would expose methods with prototypes that duplicate those used by the hllapi dll and function as a pass-through.  It is possible that you will also need to create and register both 32 bit and 64 bit proxy dlls for COM to use when marshaling calls across the 64 bit/32 bit boundary.  Your 64 bit code would then be able to instantiate the 32 bit COM server and use its methods to access the 32 bit hllapi dll."

    Sunday, November 26, 2017 3:48 PM