CodefoundryDE / LegacyWrapper

LegacyWrapper uses a x86 wrapper to call legacy dlls from a 64 bit process (or vice versa).
MIT License
80 stars 20 forks source link

cant not package with fody ? #42

Open laomms opened 2 years ago

laomms commented 2 years ago

LegacyWrapper.dll, LegacyWrapper.Common.dll... can not embedded by fody ? if embedded by fody, call exception: The system can't find the specify File

zalintyre commented 2 years ago

Hello @laomms, please raise a bug at fody.

Kind regards

laomms commented 2 years ago

I mean these two dlls cannot be packaged by fody into a single file, must exist in the folder directory ?

laomms commented 2 years ago

when call 64bit unmanaged dll in 32bit application, if have pointer related.it will thrown exception: An IntPtr or UIntPtr with an eight byte value cannot be deserialized on a machine with a four byte word size.

    public interface pkeyhelper64Dll : IDisposable
    {
        [LegacyDllMethod(CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        uint GetEditionNameFromId(uint EditionId, out IntPtr EditionName);
    }
    class Program
        {
        static IWrapperConfig _configuration = WrapperConfigBuilder.Create().TargetArchitecture(TargetArchitecture.Amd64).Build();
        public static void Main(string[] args)
                {
                        IntPtr EditionName;
            using (var client = WrapperProxyFactory<pkeyhelper64Dll>.GetInstance(_configuration))
            {
                var hResult = client.GetEditionNameFromId(0x30, out EditionName);
                if (hResult == 0)
                                {
                    Console.WriteLine(Marshal.PtrToStringAnsi( EditionName));
                                }
            }
                        Console.Read();
        }
        }

pic

zalintyre commented 2 years ago

I mean these two dlls cannot be packaged by fody into a single file, must exist in the folder directory ?

This issue is not related to LegacyWrapper, please raise an issue at fody.

zalintyre commented 2 years ago
uint

You have declared your out parameter as IntPtr, which is 32 bit wide on your system. The dll will return a pointer that is 64 bit wide. This cannot work this way.

laomms commented 2 years ago

so how can I get the pointer value

pic

or it need use unsafe code?

    [LegacyDllImport("pkeyhelper.dll")]
    public unsafe interface pkeyhelper64Dll : IDisposable
    {
        [LegacyDllMethod(CallingConvention = CallingConvention.Winapi)]
        int GetEditionNameFromId(uint EditionId,  void* EditionName);
    }
zalintyre commented 2 years ago

As I don't know how your DLL is built, this would be a nice question for StackOverflow.

laomms commented 2 years ago

this is a windows system dll. call normally under 64 bit assembly:

[DllImport("pkeyhelper.dll", EntryPoint = "GetEditionNameFromId", CharSet = CharSet.Auto)]
public extern static int GetEditionNameFromId1(int EditionId, out UIntPtr EditionName);

[DllImport("pkeyhelper.dll", EntryPoint = "GetEditionNameFromId", CharSet = CharSet.Auto)]
public extern static int GetEditionNameFromId2(int EditionId, out IntPtr EditionName);

public static void Main(string[] args)
{
            UIntPtr EditionName1;
            var hRes = GetEditionNameFromId1(0x30, out EditionName1);
            if (hRes == 0)
            {
                Console.WriteLine(Marshal.PtrToStringUni(unchecked((IntPtr)(long)(ulong)EditionName1))); //normaol
            }

            IntPtr EditionName2;
            hRes = GetEditionNameFromId2(0x30, out EditionName2);
            if (hRes == 0)
            {
                Console.WriteLine(Marshal.PtrToStringUni(EditionName2)); //normaol
            }
}
zalintyre commented 2 years ago

Have you tried using long as type for the out parameter?

laomms commented 2 years ago

I have tried every type.