简体   繁体   English

是否可以使用 Inpout32.dll 解决高端口?

[英]Is it possible to address high Ports with Inpout32.dll?

I want to address Port 0xE020 (Hex -> Dec = 57.376) but it is out of bounds for a short.我想解决端口 0xE020(十六进制 -> 十二月 = 57.376),但它暂时超出了范围。 Now, I need this to test PCI-E Extension Parallel Ports.现在,我需要它来测试 PCI-E 扩展并行端口。

Thanks to the answer to this question ( https://stackoverflow.com/a/4618383/3391678 ) I use the following working code for 32-bit environments:感谢这个问题的答案( https://stackoverflow.com/a/4618383/3391678 ),我在 32 位环境中使用了以下工作代码:

using System;
using System.Runtime.InteropServices;

namespace LPTx86
{
    public class LPT
    {
        //inpout.dll

        [DllImport("inpout32.dll")]
        private static extern void Out32(short PortAddress, short Data);

        [DllImport("inpout32.dll")]
        private static extern char Inp32(short PortAddress);

        private short _PortAddress;

        public LPT(short PortAddress)
        {
            _PortAddress = PortAddress;
        }

        public void Write(short Data)
        {
            Out32(_PortAddress, Data);
        }

        public byte Read()
        {
            return (byte)Inp32(_PortAddress);
        }
    }
}

And for 64-bit environments:对于 64 位环境:

using System;
using System.Runtime.InteropServices;

namespace LPTx64
{
    class LPT
    {
        [DllImport("inpoutx64.dll", EntryPoint = "Out32")]
        private static extern void Out32_x64(short PortAddress, short Data);

        [DllImport("inpoutx64.dll", EntryPoint = "Inp32")]
        private static extern char Inp32_x64(short PortAddress);

        private short _PortAddress;

        public LPT64(short PortAddress)
        {
            _PortAddress = PortAddress;
        }

        public void Write(short Data)
        {
            Out32_x64(_PortAddress, Data);
        }

        public byte Read()
        {
            return (byte)Inp32_x64(_PortAddress);
        }
    }
}

(Yes, I removed every piece of safeties and sanity checking, my second name is "Danger" ;) ) (是的,我删除了所有安全和健全性检查,我的第二个名字是“危险”;))

Is it possible and how can I address ports that do not fit into a short?是否有可能以及如何解决不适合短路的端口?

My header looks like this我的标题看起来像这样

void    _stdcall Out32(short PortAddress, short data);
short   _stdcall Inp32(short PortAddress);

The accepted answer works, but I think a more idiomatic way of using longer addresses is keeping the signatures consistent and casting to short in an unchecked context接受的答案有效,但我认为使用更长地址的更惯用的方法是保持签名一致并在unchecked上下文中转换为short

[DllImport("inpout32.dll")]
private static extern void Out32(short PortAddress, short data);

[DllImport("inpout32.dll")]
private static extern short Inp32(short PortAddress);

public void Write(int address, short data) {
    short portAddress;
    unchecked {
        portAddress = (short)address;
    }
    Out32(portAddress, data);
}

public short Read(int address) {
    short portAddress;
    unchecked {
        portAddress = (short)address;
    }
    return Inp32(portAddress);
}

It's possible:这是可能的:

I tried and changed the type of the port variable from short to int, i tested it and it seems to work:我尝试将端口变量的类型从 short 更改为 int,我对其进行了测试,它似乎有效:

Edit: Refactored Code to combine the data/control/status ports into one Package编辑:重构代码以将数据/控制/状态端口合并为一个包

using System;
using System.Runtime.InteropServices;

namespace LPTtestdrive
{
    class LPT_X
    {
        //inpout.dll

        [DllImport("inpout32.dll")]
        private static extern UInt32 IsInpOutDriverOpen();

        [DllImport("inpout32.dll")]
        private static extern void Out32(int PortAddress, short Data);

        [DllImport("inpout32.dll")]
        private static extern char Inp32(int PortAddress);

        //inpoutx64.dll

        [DllImport("inpoutx64.dll", EntryPoint = "IsInpOutDriverOpen")]
        private static extern UInt32 IsInpOutDriverOpen_x64();

        [DllImport("inpoutx64.dll", EntryPoint = "Out32")]
        private static extern void Out32_x64(int PortAddress, short Data);

        [DllImport("inpoutx64.dll", EntryPoint = "Inp32")]
        private static extern char Inp32_x64(int PortAddress);

        private bool _X64;
        private int DataAddress;
        private int StatusAddress;
        private int ControlAddress;

        public LPT_X(int PortAddress)
        {
            DataAddress = PortAddress;
            StatusAddress = (int)(DataAddress + 1);
            ControlAddress = (int)(DataAddress + 2);

            //now the code tries to determine if it should use inpout32.dll or inpoutx64.dll
            uint nResult = 0;

            try
            {
                Console.WriteLine("trying 32 bits");
                nResult = IsInpOutDriverOpen();
                if (nResult != 0)
                {
                    Console.WriteLine("using 32 bits");
                    return;
                }
            }
            catch (BadImageFormatException)
            {
                Console.WriteLine("32 bits failed");
            }
            catch (DllNotFoundException)
            {
                throw new ArgumentException("Unable to find InpOut32.dll");
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
            }

            try
            {
                Console.WriteLine("trying 64 bits");
                nResult = IsInpOutDriverOpen_x64();
                if (nResult != 0)
                {
                    Console.WriteLine("using 64 bits");
                    _X64 = true;
                    return;
                }
            }
            catch (BadImageFormatException)
            {
                Console.WriteLine("64 bits failed");
            }
            catch (DllNotFoundException)
            {
                throw new ArgumentException("Unable to find InpOutx64.dll");
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
            }

            throw new ArgumentException("Unable to open either inpout32 and inpoutx64");
        }

        public void WriteData(short Data)
        {
            if (_X64)
            {
                Out32_x64(DataAddress, Data);
            }
            else
            {
                Out32(DataAddress, Data);
            }
        }

        public void WriteControl(short Data)
        {
            if (_X64)
            {
                Out32_x64(ControlAddress, Data);
            }
            else
            {
                Out32(ControlAddress, Data);
            }
        }

        public byte ReadData()
        {
            if (_X64)
            {
                return (byte)Inp32_x64(DataAddress);
            }
            else
            {
                return (byte)Inp32(DataAddress);
            }
        }

        public byte ReadControl()
        {
            if (_X64)
            {
                return (byte)Inp32_x64(ControlAddress);
            }
            else
            {
                return (byte)Inp32(ControlAddress);
            }
        }

        public byte ReadStatus()
        {
            if (_X64)
            {
                return (byte)Inp32_x64(StatusAddress);
            }
            else
            {
                return (byte)Inp32(StatusAddress);
            }
        }
    }
}

Use it like this:像这样使用它:

LPT_X LPT;
int read;
int Adress = 0xE020;
try
{
    LPT = new LPT_X(Address);
    LPT.WriteData(251);
    LPT.WriteControl(0);

    read = LPT.ReadStatus();
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM