You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发Beckhoff ADS DLL测试程序时遇E0337/C2065等编译错误求助

问题:调用Beckhoff ADS DLL的测试程序编译报错

已完成读取Beckhoff PLC数据的DLL开发,DLL编译无报错,但测试程序编译时出现以下错误:

>E0337  linkage specification is incompatible with previous "AdsAmsPortEnabled" (declared at line 143)  famosAdsTestEnvironment C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h   
Error (active)  E0067   expected a '}'  famosAdsTestEnvironment C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h       
Error   C2065   'NULL': undeclared identifier   famosAdsTestEnvironment C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsDef.h   
Error   C2065   'BOOL': undeclared identifier   famosAdsTestEnvironment C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h   
Error   C2065   'pbEnabled': undeclared identifier  famosAdsTestEnvironment C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h   
Error   C2061   syntax error: identifier 'BOOL' famosAdsTestEnvironment C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h   

错误均指向Beckhoff提供的只读ADS头文件,推测是头文件引用问题,相关代码如下:

DLL头文件(famosAdsLibrary.h)

#pragma once
#include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsDef.h"
#include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h"

#ifdef FAMOSADSLIBRARY_EXPORTS
#define FAMOSADSLIBRARY_API __declspec(dllexport)
#else
#define FAMOSADSLIBRARY_API __declspec(dllimport)
#endif 

class FAMOSADSLIBRARY_API adsCommunication {
private:
long      nErr, nPort = 0;
AmsAddr   Addr;
PAmsAddr  pAddr = &Addr;
int       adress;
int       datatyp;

public:

adsCommunication(int datatyp = 0x4, int adress = 0x0) {
    this->datatyp = datatyp;
    this->adress = adress;

}

void connectADS();
void disconnectADS();
float readADS();
void writeADS(int data);
};

DLL主程序(famosAdsLibrary.cpp)

#include "pch.h"
#include "famosAdsLibrary.h"
#include <iostream>
#include "framework.h"
#include <conio.h>
#include <windows.h>

using namespace std;


BOOL APIENTRY DllMain( HMODULE hModule,
                   DWORD  ul_reason_for_call,
                   LPVOID lpReserved
                 )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
    break;
}
return TRUE;
}

void adsCommunication::connectADS() {

// Open communication port on the ADS router
nPort = AdsPortOpen();
nErr = AdsGetLocalAddress(pAddr);
if (nErr) cerr << "Error: AdsGetLocalAddress: " << nErr << '\n';
pAddr->port = 851;

}

float adsCommunication::readADS() {
INT data = 0;
nErr = AdsSyncReadReq(pAddr, 0x4020, adress, datatyp, &data);
if (nErr) cerr << "Error: AdsSyncReadReq: " << nErr << '\n';
cout << data << endl;
return data;
}

void adsCommunication::writeADS(int data) {

nErr = AdsSyncWriteReq(pAddr, 0x4020, adress, datatyp, &data);
if (nErr) cerr << "Error: AdsSyncWriteReq: " << nErr << '\n';
}


void adsCommunication::disconnectADS() {
nErr = AdsPortClose();
if (nErr) cerr << "Error: AdsPortClose: " << nErr << '\n';
}

测试程序头文件(Main.h)

#pragma once

#include <famosAdsLibrary.h>
#include <Windows.h>

测试程序主程序(Main.cpp)

#include "Main.h"


int main() {

int       value = 0;

adsCommunication data(0x4, 0x0);

data.connectADS();

while (1)
{
    value = data.readADS();

    if (value >= 800) {

        value = 0;

        data.writeADS(wert);
    }
}

data.disconnectADS();


system("PAUSE");

return 0;
}

出错的Beckhoff头文件片段(TcAdsAPI.h)

#ifndef __ADSAPI_H__
#define __ADSAPI_H__

#define ADSAPIERR_NOERROR           0x0000
#ifdef __cplusplus
extern "C"
{
#endif

//other dllexports without error


__declspec( dllexport )
long __stdcall AdsAmsPortEnabled(BOOL *pbEnabled);

// more dllexports without error
__declspec( dllexport )
long __stdcall AdsAmsPortEnabledEx(long nPort, BOOL *pbEnabled);

解决方案

1. 修复头文件引用顺序,确保系统头文件优先

Beckhoff的ADS头文件依赖Windows.h定义的BOOL、NULL等类型,必须在引用TcAdsDef.h和TcAdsAPI.h前包含Windows.h:

修改DLL头文件(famosAdsLibrary.h):

#pragma once
#include <windows.h>  // 移到最前面
#include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsDef.h"
#include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h"

#ifdef FAMOSADSLIBRARY_EXPORTS
#define FAMOSADSLIBRARY_API __declspec(dllexport)
#else
#define FAMOSADSLIBRARY_API __declspec(dllimport)
#endif 
// ... 其余代码不变

修改测试程序头文件(Main.h):

#pragma once
#include <Windows.h>  // 移到famosAdsLibrary.h之前
#include <famosAdsLibrary.h>

2. 确认extern "C"块的完整性

报错中的expected a '}'说明TcAdsAPI.h里的extern "C"块可能没有正确闭合。检查该头文件末尾是否有:

#ifdef __cplusplus
}
#endif

如果缺失,需重新获取官方完整的ADS头文件。

3. 修复测试程序中的变量错误

测试主程序里的data.writeADS(wert);中wert未定义,应改为value:

if (value >= 800) {
    value = 0;
    data.writeADS(value);  // 替换wert为value
}

4. 统一编译环境设置

确保DLL和测试程序使用相同的编译选项:

  • 均为32位或64位编译(需匹配ADS DLL的对应版本)
  • 使用相同的运行时库(如MT/MD)

内容的提问来源于stack exchange,提问作者excellent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 20:16:13