#c #c #windows #java-native-interface #symlink
Вопрос:
Я ищу возможность создания символических ссылок (мягких ссылок) из Java на компьютере с Windows Vista/ 2008. Я доволен идеей, что для этого мне нужно обратиться к JNI. Однако мне нужна помощь по фактическому коду C. Каков соответствующий системный вызов для создания ссылки? Мы были бы очень признательны за ссылки на хорошую документацию по этому вопросу.
Ответ №1:
Символические ссылки в Windows создаются с помощью функции API CreateSymbolicLink, которая принимает параметры, очень похожие на аргументы командной строки, принятые утилитой командной строки Mklink.
Предполагая, что вы правильно ссылаетесь на заголовки JNI и Win32 SDK, ваш код, таким образом, может быть таким же простым, как:
JNIEXPORT jboolean JNICALL Java_ClassName_MethodName
(JNIEnv *env, jstring symLinkName, jstring targetName)
{
const char *nativeSymLinkName = env->GetStringUTFChars(symLinkName, 0);
const char *nativeTargetName = env->GetStringUTFChars(targetName, 0);
jboolean success = (CreateSymbolicLink(nativeSymLinkName, nativeTargetName, 0) != 0);
env->ReleaseStringUTFChars(symLinkName, nativeSymLinkName);
env->ReleaseStringUTFChars(targetName, nativeTargetName);
return success;
}
Обратите внимание, что это просто не укладывается у меня в голове, и я уже целую вечность не имел дела с JNI, поэтому, возможно, я упустил некоторые тонкости этой работы…
Ответ №2:
Это было в моем списке, чтобы попробовать, из моих заметок:
API:
http://msdn.microsoft.com/en-us/library/aa363866(ПРОТИВ 85).aspx
BOOLEAN WINAPI CreateSymbolicLink(
__in LPTSTR lpSymlinkFileName,
__in LPTSTR lpTargetFileName,
__in DWORD dwFlags
);
Некоторые примеры C# :
Пример C , это cnp из другой статьи, которую я читал. Я не тестировал его, поэтому используйте его с осторожностью.
typedef BOOL (WINAPI* CreateSymbolicLinkProc) (LPCSTR, LPCSTR, DWORD);
void main(int argc, char *argv[])
{
HMODULE h;
CreateSymbolicLinkProc CreateSymbolicLink_func;
LPCSTR link = argv[1];
LPCSTR target = argv[2];
DWORD flags = 0;
h = LoadLibrary("kernel32");
CreateSymbolicLink_func =
(CreateSymbolicLinkProc)GetProcAddress(h,
if (CreateSymbolicLink_func == NULL)
{
fprintf(stderr, "CreateSymbolicLinkA not availablen");
} else
{
if ((*CreateSymbolicLink_func)(link, target, flags) == 0)
{
fprintf(stderr, "CreateSymbolicLink failed: %dn",
GetLastError());
} else
{
printf("Symbolic link created.");
}
}
}
Сказав это, я бы не стал использовать этот код 🙂 Я бы либо был склонен к развилке mklink, либо посмотрел на родную библиотеку из jruby/jpython (извините, я не могу найти ее в банкомате, так как мое сетевое подключение слабое). Я, кажется, припоминаю, что jruby написал библиотеку, которая объединяет различные API posix в java (думает, как chown, которые необходимы для соответствия требованиям ruby, но не являются кроссплатформенными). Этой библиотекой пользуются люди из jpython, которые, похоже, очень довольны ею. Я был бы удивлен, если бы эта библиотека не предлагала поддержку sim — ссылок.
Ответ №3:
Не могли бы вы просто вызвать командную строку и использовать mklink?
Комментарии:
1. Нет! Я хочу использовать соответствующий вызов C/C напрямую.
2. Справедливо. Но есть ли какая-то конкретная причина? Я имею в виду, есть ли необходимые вам функции, которые недоступны через mklink или аналогичные?
3. Я упомянул об этом как о варианте, это разумный выбор, но вы платите накладные расходы за создание процесса.
4. У меня уже есть библиотека JNI, которую мне нужно расширить. Поэтому просто вызвать API гораздо более желательно, чем создавать новый процесс для вызова отдельного приложения, беспокоиться о пути к этому приложению, записывать его код возврата, чтобы узнать, произошло ли создание и т. Д.
5. Поразмыслив, я изменил свой голос «против» на «против». Возможно, я не хочу делать это таким образом, но это не неправильный ответ и может быть полезен другим.