###やりたいことサンプル:
C++
1int func(){//a (ライブラリ中で定義) 2 return 1; 3} 4 5int func(){//b (ユーザーソースで定義) 6 return 2; 7} 8 9int main(){ 10 func();//bが呼び出されるようにしたい 11 return 0; 12}
aの記述はいじらず、b側(ソース中の記述)だけでmainからbが呼び出されるように出来ないか。
__attribute__((weak))
の反対の機能を持つ__attribute__((strong))
(仮称)みたいなのがあって強制的にオーバーライド出来たりすると嬉しいのですけれど、見つけられていません。
一般的にはリンカの--wrapオブションで...という手段もあるようですが、特殊事情(下記)で使えませんでした。
###実際の状況:
Arduino IDE(1.8.13 gcc(7.3.0)/C++ ターゲットArduino UNO Win10)において、シリアル通信でハードウェアフロー(の一部、CTS)を実現したい。そのため、送信の割り込み処理を置き換えたい。
しかし、Arduinoのライブラリでは、割り込みハンドラはベタに定義されていて、ユーザー側で送信割り込みハンドラを設定しようとすると多重定義でリンク時エラーになる。
Arduino
1#include "mySerial.h" 2volatile bool irq=false; 3void setup() { 4 MySerial.begin(115200); 5 MySerial.println("Hello, world.\n"); 6 delay(10); 7 MySerial.println(irq); //以下の割り込みが実行されれば1 8} 9 10void loop() { 11} 12 13ISR(USART_UDRE_vect) 14{ 15 irq=true; 16 MySerial._tx_udr_empty_irq();//元の割り込みと同じ処理 17}
mySerial.h
C++
1#pragma once 2#include <Arduino.h> 3#include <HardwareSerial.h> 4#include <HardwareSerial_private.h> 5class mySerial: public HardwareSerial { 6 using HardwareSerial::HardwareSerial; 7}; 8mySerial MySerial(&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0);
ISRマクロの定義(ライブラリ内)
C++
1# define ISR(vector, ...) \ 2 extern "C" void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \ 3 void vector (void)
エラーメッセージ
Text
1HardwareSerial0.cpp.o (symbol from plugin): In function `Serial': 2(.text+0x0): multiple definition of `__vector_19'
###[試行1]ライブラリを書き換える
hardware/arduino/avr/cores中のHardwareSerial.cpp中の
ISR(USART_UDRE_vect)
を
ISR(USART_UDRE_vect,__attribute__((weak)))
とする
これにより、上記ソースのビルドが正常終了し、
Text
1Hello, world. 21
がSerialに出力される。つまり、オーバーライド自体は出来ていて、普通に使う分には従来動作も確保できるので悪くはない。が、やはりライブラリを書き換えるというのは邪道な感。また、Arduino IDEのインストールの仕方によって?ライブラリの場所がインストールディレクトリになったりUsers/ユーザー/AppData/Local/Arudino15以下になったりする様子。自分で環境を変えた時の再現も他人に伝えるのも面倒。
###[試行2]リンカオプション --wrap を使えないか検討
割り込みベクタ名が特別に認識されるようで(__attribute__((signal))
の作用?) __wrap_の関数名とすると割り込みハンドラとして機能しない様子。NG。まぁ、こちらもIDEのコンパイルオプションファイルをいじらなきゃいけなくなるので、たとえ出来ても使いたくない方法ではあるのですが。
なにか手はありますでしょうか...
あなたの回答
tips
プレビュー