使用其他宏作为参数调用C宏

时间:2017-02-14 14:24:01

标签: c macros constants

我在尝试将宏常量作为参数传递给宏函数时遇到了问题。

考虑以下代码 -

public class UserNotificationCenterDelegate : UNUserNotificationCenterDelegate
{

     public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
    {
        try
        {
          NSString[] keys = { new NSString(Constants.PushNotificationInfoKeys.NOTIFICATION_TYPE) };

           var mystring = new NSString(Constants.PushNotificationInfoKeys.NOTIFICATION_TYPE);

            var alertId = response.Notification.GetDictionaryOfValuesFromKeys(keys).ValueForKey(mystring);  //App crashes on this line

        }catch (Exception ex)
        {

            Console.WriteLine(ex.Message + ex.StackTrace);
        }

}

第二个日志语句编译但第一个日志语句生成以下编译错误 -

UserInfo

为什么会这样?我希望能够定义一组日志级别和模块常量,并在调用LOG()宏时使用它们。

2 个答案:

答案 0 :(得分:0)

我可以看到 three 两个问题:

  1. 您将在同一范围内拥有多个import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; import org.libnodave.Nodave; import org.libnodave.PLCinterface; import org.libnodave.S7Connection; import org.libnodave.TCPConnection; public class ConnectPLC { public static void main(String[] args) { S7Connection dc; String ip = "192.168.0.61"; Socket sock; OutputStream oStream = null; InputStream iStream = null; PLCinterface di; int slot = 1; try { System.out.println("Inside the try block"); sock = new Socket(ip, 102); if(sock != null) { oStream = sock.getOutputStream(); iStream = sock.getInputStream(); di = new PLCinterface( oStream, iStream, "PLCInterface1", 0, Nodave.PROTOCOL_ISOTCP); di.initAdapter(); dc = new TCPConnection(di, 0, slot); int res = dc.connectPLC(); int x = 0; if (0 == res) { System.out.println("++++++++++++++++++++++++++++++++++++"); System.out.println("PLC is connected"); System.out.println("++++++++++++++++++++++++++++++++++++"); byte[] byteArray = new byte[4]; x = dc.readBytes(Nodave.DB, 2, 0, 4, byteArray); System.out.println("The value of x is "+x); for (int i = 0; i < byteArray.length ; i++) { System.out.println("The value at index "+i+" is "+byteArray[i]); } System.out.println(dc.getINT(0)); System.out.println(dc.getINT(2)); if (x == 0) { //byte[] byteArray = dc.msgIn; for (int i = 0; i < byteArray.length ; i++) { System.out.println("The value at index "+i+" is "+byteArray[i]); } System.out.println(dc.getINT(0)); System.out.println(dc.getINT(2)); } } else { System.out.println("PLC is not connected"); } System.out.println("Now disconnecting\n"); dc.disconnectPLC(); di.disconnectAdapter(); System.out.println(); } } catch (UnknownHostException e) { System.out.println("Unknown Host Exception is Caught during the declaration of the socket"); e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block System.out.println("IO Exception is Caught during the declaration of the socket"); e.printStackTrace(); } } } 个变量。
  2. 你错过了一个逗号(由@Ninetainedo指出)。
  3. 您对格式化的字符串不做任何操作。
  4. 我更愿意声明一个接受日志级别的全局msg函数,并使用宏来缩短调用它。

答案 1 :(得分:0)

宏的一个问题是它在代码块中的随机位置声明了一个变量,C89不允许:允许您仅在块的顶部声明变量。即使使用C99编译器,问题也不会消失,因为现在您可以在相同的范围内引入多个相同名称的声明,这是禁止的。

您可以使用do/while(0) trick来解决此问题:

#define LOG(lvl,mod,fmt,...) do {\
    char msg[256] = {0}; \
    snprintf(msg, 256, "%s: %d: "fmt,mod,lvl,##__VA_ARGS__) \
} while(0)