Эффективная передача данных от Java до C++ на окнах

Это должно сработать, если вы хотите сохранить первое вхождение каждого нецифрового слова. Вы всегда можете обмануть условие, чтобы оно имело максимум две цифры.

def cleanup(s):
    words = set()
    for (word, nextword) in zip(s.split(), s.split()[1:] + [None]):
        if word.isdigit():
            yield word
            continue
        if not word in words:
            words.add(word)
            yield word
        elif nextword and nextword.isdigit():
            yield word


print ' '.join(cleanup("East Zone Mbc26 East Zone 1 2nd S11B Smds Smoke Damper 1 Status"))
print ' '.join(cleanup("GF Command Room 1 Unit 1 Flow Temperature Temperature"))

Выход

East Zone Mbc26 Zone 1 2nd S11B Smds Smoke Damper 1 Status
GF Command Room 1 Unit 1 Flow Temperature
6
задан 5 November 2008 в 22:08
поделиться

11 ответов

Необходимо смотреть на Буферы Протокола от Google, который поддерживает и C++ и Java.

7
ответ дан 8 December 2019 в 13:51
поделиться

Именованные каналы были бы более эффективными, чем TCP, но как насчет того, чтобы просто использовать блоки общей памяти?

Я не знаю, какие примитивы существуют на стороне Java для взаимодействия через интерфейс с общей памятью, но со стороны C++ было бы более эффективно получить доступ к данным в общей памяти, чем чтение это или из сокета или из именованного канала. Необходимо было бы реализовать собственное управление потоком и блокирующиеся примитивы, но они могли быть довольно прямыми.

4
ответ дан 8 December 2019 в 13:51
поделиться

Я использовал бы локальный сокет, который является, как Вы заявляете, самый межплатформенный метод.

Копии пространства пользователя ядра не должны быть проблемой начиная ни с какого другого метода, который Вы могли выбрать, будет requiere этот вид копии за исключением, возможно, общей памяти. Это доступно в каждой системе Unix, и также Windows имеет свой способ сделать его

Для использования общей памяти в Java, единственный путь состоит в том, чтобы реализовать его посредством собственного.DLL/.SO и JNI для доступа к нему.

4
ответ дан 8 December 2019 в 13:51
поделиться

Если Вы довольны записью JNI, рассматриваете Повышение. Межпроцессный. Это даст Вам портативную общую память и на Linux и на Windows. Помните, что нет никакого распространения в прямом и обратном направлениях ядра для чтения/записи общей памяти.

1
ответ дан 8 December 2019 в 13:51
поделиться

Я использовал бы локальный сокет с отрицательным подтверждением UDP, если бы скорость передачи будет слишком высокой для TCP (хотя я попробовал бы TCP сначала и подтвердил бы, что это - проблема). Там должно быть минимальным, если таковые имеются, пакеты, отброшенные, если Вы делаете потоковую передачу на той же машине, но добавление отрицательного слоя подтверждения будет заботиться о том случае для Вас.

0
ответ дан 8 December 2019 в 13:51
поделиться

Как насчет того, чтобы использовать System.out и System.in?

Если это не подходит, то Сокеты являются Вашим лучшим выбором.

0
ответ дан 8 December 2019 в 13:51
поделиться

Если Ваш процесс C++ запускает процесс Java, он мог бы извлечь выгоду из inheritedChannel. Кроме того, если процесс Java использует файл, я рекомендую исследование transferTo и transferFrom методов. Чтобы выполнение файла зарегистрировало IO, они стараются не напрасно смещаться назад и вперед между пространством ядра и пользователем; та же оптимизация могла бы умереть при использовании специального канала сокета.

0
ответ дан 8 December 2019 в 13:51
поделиться

Я рекомендую UDP "соединение", которое подтверждает каждый Энный пакет, который был получен без отказа и запрашивает повторную передачу нескольких пакетов, которые это пропустит.

0
ответ дан 8 December 2019 в 13:51
поделиться

Я отговорил бы от JNI, потому что очень трудно отладить. Если код C++ segfaults или выдаст неперехваченное исключение, то Ваша JVM откажет, и Вы будете понятия не иметь почему.

-2
ответ дан 8 December 2019 в 13:51
поделиться

Самым быстрым решением будет отображение памяти в разделяемом сегменте памяти и реализация кольцевого буфера или другого механизма передачи сообщений. В C ++ это просто, а в Java у вас есть метод FileChannel.ma p, который делает это возможным.

Следующей альтернативой будет использование stdin / stdout двух процессов. Если один может выполнить другой, это может быть довольно быстро.

Наконец, как вы заметили, вы можете выполнять ввод-вывод сокета. Для потокового видео это не лучший вариант, но если вы передаете XML, накладные расходы будут минимальными по сравнению с другой обработкой.

2
ответ дан 8 December 2019 в 13:51
поделиться

Если это большой кусок данных в «одном» вызове функции, я бы порекомендовал JNI.

Взгляните на это: Совместное использование выходных потоков через интерфейс jni

Фрагмент из статьи, он передает данные из c ++ в java, обратное тоже будет легко сделать:

В целом, общая стратегия обмена двоичными данными (аудио / видео файлы, изображения и т. д.) из C с Java требует массивов байтов. Вы создаете массив байтов Java в C следующим образом:

const char[] rawData = {0,1,2,3,4,5,6,7,8,9}; //Or get some raw data from somewhere
int dataSize = sizeof(rawData);
printf("Building raw data array copy\n");
jbyteArray rawDataCopy = env->NewByteArray(dataSize);
env->SetByteArrayRegion(rawDataCopy, 0, dataSize, rawData);

И передаете его Java следующим образом:

printf("Finding callback method\n");
//Assumes obj is the Java instance that will receive the raw data via callback
jmethodID aMethodId = env->GetMethodID(env->GetObjectClass(obj),"handleData","([B)V");
if(0==aMethodId) throw MyRuntimeException("Method not found error");
printf("Invoking the callback\n");
env->CallVoidMethod(obj,aMethodId, &rawDataCopy);

у вас будет объект Java, который будет выглядеть примерно так:

public class MyDataHandler {
  OutputStream dataStream;
  public MyDataHandler(OutputStream writeTo) { dataStream = writeTo;}
  public void handleData(byte[] incomingData) { dataStream.write(incomingData); }
}

Этот обработчик будет передан в C через собственный метод вот так:

public class NativeIntegration {
  public native void generateBinaryWithHandler(MyDataHandler handler);

  //Here we assume response is something like a network stream
  public void doCallNativeFunction(ResponseStream response) {
    MyDataHandler handler = new MyDataHandler(response);
    generateBinaryWithHandler(handler);
  }
}

Также вы можете использовать другие технологии: CORBA, ASN.1 ( инструмент ASN.1 ), UDP или TCP

1
ответ дан 8 December 2019 в 13:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: