【问题标题】:Use of a manufacturer's DLL to control a stepper controller via USB using C++使用制造商的 DLL 通过 USB 使用 C++ 控制步进控制器
【发布时间】:2014-08-18 00:09:11
【问题描述】:

简介 上完大学课程后,我正在重新自学 C++。我最近购买了一个 Arcus Performax PMX-4EX-SA-TB9 步进电机控制器,它有一个我打算使用的 USB 连接。该公司提供使用其专有代码手动控制步进器的软件,并在其软件中提供一个终端,您可以在其中向控制器发送单行代码以控制步进器。你可以控制加速度和最高速度以及各种东西。玩起来很有趣,但现在我想更进一步。在线手册讨论了使用 C++ 为步进器编写自己的程序,我下载了我认为我需要的文件。我有一个 DLL 文件、一个 lib 文件和一个头文件。因此,我了解到 DLL 文件是在可执行文件运行时使用的动态链接库。我通读了 lib 文件和头文件,发现我认为头文件中的一些函数声明类似于一些电机命令。我将在下面插入头文件。

我的问题

我可以使用 DLL 文件以及 lib 和头文件来使用我在头文件中看到的函数来控制这个设备吗?我如何加载这一切?有人愿意使用下面包含的 fnPerformaxComDoMove 函数编写一个简短的小示例吗?这样我就可以从那里走了?我正在使用 Visual Studio C++ 2013,并且我已经完成了有关创建和使用我自己制作的 DLL 的在线教程,但与这个相比,这些都显得如此简单。

我的理解不足

我相信,由于我获得了 DLL、头文件和 lib 文件,因此我将使用 _declspec(dllexport) 定义而不是导入版本。所有的函数声明都以“BOOL”开头,然后是“PERFORMAXCOM_API”,然后是“_stdcall”,我只习惯于查看类型,然后是函数名,然后是括号中的参数。在所有不同的函数面前,“PERFORMAX_API”和“_stdcall”是什么意思?我知道 DWORD 是双字,是一个 32 位整数,但有些参数要求一个轴,比如 x、y 和 z……当他们本来可以要求一个字符时,为什么他们想要一个数字?非常感谢任何可以帮助我提供任何信息的人。我非常想学习如何使用它。

标题

    #ifdef PERFORMAXCOM_EXPORTS
    #define PERFORMAXCOM_API __declspec(dllexport)
    #else
    #define PERFORMAXCOM_API __declspec(dllimport)
    #endif

    extern PERFORMAXCOM_API int nPerformaxCom;

    #ifdef __cplusplus
    extern "C" {
    #endif

    PERFORMAXCOM_API int fnPerformaxCom(void);

    //USB reset

    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComUSBReset(IN HANDLE pHandle);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComFlush(IN HANDLE pHandle);

    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComGetNumDevices(OUT LPDWORD         lpNumDevices);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComGetProductString(IN DWORD dwNumDevices, OUT LPVOID lpDeviceString, IN DWORD dwOptions);    
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComOpen(IN DWORD dwDeviceNum, OUT HANDLE* pHandle);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComClose(IN HANDLE pHandle);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComSetTimeouts(IN DWORD dwReadTimeout, DWORD dwWriteTimeout);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComSendRecv(IN HANDLE pHandle, IN LPVOID wBuffer, IN DWORD dwNumBytesToWrite,IN DWORD dwNumBytesToRead,OUT LPVOID rBuffer);

    signed int PERFORMAXCOM_API _stdcall fnPerformaxMove(IN HANDLE pHandle, 
                                                        IN int commandCode, 
                                                        IN int axes,
                                                IN int moveDir,
                                                IN long *value,
                                                IN int modelCode);

    signed int PERFORMAXCOM_API _stdcall fnPerformaxCommandReply(IN HANDLE pHandle, 
                                                         IN char *command, 
                                                         IN char *reply);

    signed int PERFORMAXCOM_API _stdcall fnPerformaxIO(IN HANDLE pHandle, 
                                                IN int commandCode, 
                                                IN int bitNumber,
                                                IN long *value,
                                                IN int modelCode);

    signed int PERFORMAXCOM_API _stdcall fnPerformaxMotorStat(IN HANDLE pHandle, 
                                                IN int commandCode, 
                                                IN int axes,
                                                IN long *value,
                                                IN int modelCode);

    signed int PERFORMAXCOM_API _stdcall fnPerformaxSpeedAccel(IN HANDLE pHandle, 
                                                       IN int commandCode, 
                                                       IN int axes,
                                                       IN long *value,
                                                       IN int modelCode);

    signed int PERFORMAXCOM_API _stdcall fnPerformaxGeneral(IN HANDLE pHandle, 
                                                    IN int commandCode, 
                                                    IN int axes,
                                                    IN long *value,  
                                                    IN int modelCode);


    long PERFORMAXCOM_API _stdcall fnPerformaxComGetAxisStatus(IN HANDLE pHandle,DWORD dwAxisNumber);
    long PERFORMAXCOM_API _stdcall fnPerformaxComGetPulseSpeed(IN HANDLE pHandle,DWORD dwAxisNumber);
    long PERFORMAXCOM_API _stdcall fnPerformaxComGetPulsePos(IN HANDLE pHandle,DWORD dwAxisNumber);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComSetPulsePos(IN HANDLE pHandle,DWORD dwAxisNumber, DWORD pos);
    long PERFORMAXCOM_API _stdcall fnPerformaxComGetEncoderPos(IN HANDLE pHandle,DWORD dwAxisNumber);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComSetEncoderPos(IN HANDLE pHandle,DWORD dwAxisNumber, DWORD pos);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComSetPolarity(IN HANDLE pHandle,DWORD dwAxisNumber,DWORD dwPolarity);
    long PERFORMAXCOM_API _stdcall fnPerformaxComGetPolarity(IN HANDLE pHandle,DWORD dwAxisNumber);
    long PERFORMAXCOM_API _stdcall fnPerformaxComGetDIOSetup(IN HANDLE pHandle);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComSetDIOSetup(IN HANDLE pHandle, DWORD dio_setup);
    long PERFORMAXCOM_API _stdcall fnPerformaxComGetDIO(IN HANDLE pHandle);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComGetDIOBit(IN HANDLE pHandle,DWORD bitn);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComSetDIO(IN HANDLE pHandle,DWORD dio_value );
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComSetDIOBit(IN HANDLE pHandle,DWORD bitn,DWORD bitv );
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComDoHome(IN HANDLE pHandle,
                                                               DWORD axis,
                                                               DWORD dir,
                                                       DWORD low_speed,
                                                       DWORD high_speed,
                                                       DWORD accel_time,
                                                       DWORD decel_time,
                                                       DWORD search_mode,
                                                       DWORD ramp_mode);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComDoMove(IN HANDLE pHandle,
                                                       DWORD axisn,
                                                       DWORD target,
                                                       DWORD low_speed,
                                                       DWORD high_speed,
                                                       DWORD accel_time,
                                                       DWORD decel_time);
    BOOL PERFORMAXCOM_API _stdcall fnPerformaxComStop(IN HANDLE pHandle,
                                                       DWORD axisn,
                                                       DWORD ramp_stop);






    #ifdef __cplusplus
    }
    #endif

【问题讨论】:

    标签: c++ dll hardware header-files motordriver


    【解决方案1】:

    方法前缀 __declspec(dllimport) 和 __declspec(dllexport) 是 Microsoft 的语言扩展,它指示编译器导入或导出哪些符号。

    _stdcall 是 MSVC 编译器的调用约定。

    Stackoverflow 已经得到了更好的回复,这里的链接可以帮助您获得非常清晰的问题答案。需要几分钟才能完成。

    What is __stdcall?

    what does __declspec(dllimport) really mean?

    关于您关于 Axes 的问题,char 也是数字类型(与整数相同),它接受较小的值(字节 syze)。但是,如果数据类型的大小与微处理器体系结构相同,那么您正在使用的这种硬件中的微处理器将执行得更快。如果 Arcus Performax PMX-4EX-SA-TB9 是 32 位硬件(当今世界的大多数硬件都是,DWORD 的执行速度将比 char 快得多。

    希望这会有所帮助。

    问候 卡哈尔

    【讨论】:

      【解决方案2】:

      当您在项目中使用头文件时,PERFORMAXCOM_API 将变为 __declspec(dllimport),因此每个函数都被声明为 DLL 导入。 _stdcall 是每个函数的调用约定。基本上你可以忽略这些细节并编写代码来调用函数。

      【讨论】:

      • 所以基本上我可以通过键入以下内容来调用该函数: fnPerformaxComStop(IN HANDLE pHandle, DWORD axisn, DWORD ramp_stop);一旦我了解 IN HANDLE pHandle 是什么,替换了参数,就像这样? fnPerformaxComStop(someHandle, someAxisn, someRamp)
      • 是的,然后将 .lib 文件添加到您的链接器设置中。这和你学习的 DLL 教程真的没有什么不同。
      • 我在 Virtual Studio 中添加了所有这些,就像在教程中一样。我的困惑源于弄清楚这些论点要求的是什么。例如,我想调用 fnPerformaxComDoMove 但我不知道 IN HANDLE phandle 是什么......或者它的类型。我查看了没有真正帮助的头文件和 lib 文件。该函数的下一个参数是 DWORD axisn,它是 32 位的双字类型,但它要求 x、y、z 还是 u?还是一个数字?我相信其他论点对我来说是不言自明的,但我无法对其进行测试,直到我可以让至少一个函数工作。
      • 要理解这些参数,您必须使用制造商的文档或示例代码。
      • 被 5 分钟计时器搞砸了。我补充说 HANDLE 是指向 ARCUS 设备的指针。它是通过调用 OPEN() 方法获得的。您需要设备 HANDLE 来调用其他方法,例如 MOVE(),因为可能有超过 1 个 USB 步进设备。这些方法中的所有参数都指定了变量的类型和用途。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多