Каким образом создать несколько сборок с различным кодом на основе одного проекта?
Имеется библиотека FOCAS на C от производителя CNC станков FANUC для которой необходимо реализовать JNA обёртку. Проблема заключается в том, что тип данных параметров функций различается в зависимости от модели/серии CNC-машины, к которой выполняется подключение.
Приведу конкретный пример. Имеется функция cnc_statinfo
FWLIBAPI short WINAPI cnc_statinfo( unsigned short FlibHndl, ODBST* statinfo );
где параметром передаётся указатель на структуру ODBST, которая выглядит по разному в зависимости от используемой модели/серии:
// Series 15/15i
typedef struct odbst {
short dummy[2];
short aut;
short manual;
short run;
short edit;
short motion;
short mstb;
short emergency;
short write;
short labelskip;
short alarm;
short warning;
short battery;
} ODBST;
// Series 16/18/21, 16i/18i/21i, 0i, 30i/31i/32i, Power Mate i, PMi-A
typedef struct odbst {
short hdck;
short tmmode;
short aut;
short run;
short motion;
short mstb;
short emergency;
short alarm;
short edit;
} ODBST;
// Series 16i/18i-W
typedef struct odbst {
short dummy[2];
short aut;
short run;
short motion;
short mstb;
short emergency;
short alarm;
short edit;
} ODBST;
Помимо этого, для каждой определённой серии/модели станка имеется своя версия заголовочного файла, содержимое которых различается значением и наличием некоторых констант препроцессора (могу ошибаться в терминах).
Для подключения к CNC, на данный момент, используется примерно такой код:
Интерфейс Fwlib64Library
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.ptr.ShortByReference;
import com.sun.jna.ptr.NativeLongByReference;
public interface Fwlib64Library extends Library
{
static final Fwlib64Library INSTANCE = Native.load( "Fwlib64", Fwlib64Library.class );
short cnc_allclibhndl3( String host, short port, NativeLong timeout, ShortByReference libHandle );
short cnc_freelibhndl( short libHandle );
short cnc_alarm2( short libHandle, NativeLongByReference alarm );
short cnc_statinfo( short libHandle, ODBST statInfo );
}
Класс ODBST
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
@FieldOrder({ "hdck", "tmmode", "aut", "run", "motion", "mstb", "emergency", "alarm", "edit" })
public class ODBST extends Structure
{
public short hdck;
public short tmmode;
public short aut;
public short run;
public short motion;
public short mstb;
public short emergency;
public short alarm;
public short edit;
public ODBST() { super(); }
public ODBST( short hdck, short tmmode, short aut, short run, short motion, short mstb, short emergency, short alarm, short edit )
{
super();
this.hdck = hdck;
this.tmmode = tmmode;
this.aut = aut;
this.run = run;
this.motion = motion;
this.mstb = mstb;
this.emergency = emergency;
this.alarm = alarm;
this.edit = edit;
}
public ODBST( Pointer peer ) { super( peer ); }
public static class ByReference extends ODBST implements Structure.ByReference { }
public static class ByValue extends ODBST implements Structure.ByValue { }
}
Пример использования
// зависимая библиотека Fwlibe64.dll необходимая для TCP/IP соединений,
// которую необходимо "подгрузить" для исключения ошибки EW_NODLL(-15)
Fwlibe64Library fwlibe = Fwlibe64Library.INSTANCE;
Fwlib64Library lib = Fwlib64Library.INSTANCE;
String host = "42.cnc.loc";
short port = 8193;
NativeLong timeout = new NativeLong( 10, true );
final ShortByReference libHandle = new ShortByReference();
final short connectionRetCode = lib.cnc_allclibhndl3( host, port, timeout, libHandle );
if( connectionRetCode == 0 && libHandle.getValue() != 0 )
{
ODBST outStatInfo = new ODBST();
lib.cnc_statinfo( libHandle.getValue(), outStatInfo );
boolean isStop = outStatInfo.run == 1;
boolean isHold = outStatInfo.run == 2;
boolean isRun = outStatInfo.run == 3;
short freeLibHandleRetCode = lib.cnc_freelibhndl( libHandle.getValue() );
}
Так как тип параметра (в конкретном случае ODBST statinfo
в функции cnc_statinfo
) должен различаться в зависимости от типа/версии используемой библиотеки Fwlib64.dll/заголовочного файла, то отсюда можно сделать вывод, что для каждой модели/серии CNC необходимо создавать отдельную JNA-обёртку/сборку (к примеру fwlib64-30i-1.0.0.jar
, fwlib64-pmia-1.0.0.jar
, и т.д.), или я не прав и здесь есть какие-то дополнительные варианты?
Также, хотя в коде есть различия, всё таки большинство кода/типов/методов являются одинаковыми и вполне резонно хотелось бы не повторять/копировать этот код из одной JNA-обёртки в другую и по этому поводу имеются следующие варианты (пока покрытые мраком):
- Использовать различные Git ветки
К примеру ветку с основным кодом и для каждой серии CNC отдельную, а при релизе/сборке/публикации всё это каким это образом сливать/собирать с помощью Maven/GitLab. - Использовать разные пакеты/пространства имён
Для каждой модели/версии назначить свой пакет (напримерfwlib64.series15
,fwlib64.series_pmi
и т.д.) и опять-же собирать различные сборки с помощью Maven/GitLab.
Вопрос
Каким образом создать несколько сборок JNA-обёрток с определённой кодовой базой/пакетами/ветками с помощью Maven и GitLab?