C++ ошибка CLI C3767: функция (функции) кандидата, не доступная

Сценарий

threads = []
(1..5).each do |i|
  threads << Thread.new { Thread.current[:output] = `echo Hi from thread ##{i}` }
end
threads.each do |t|
  t.join
  puts t[:output]
end

иллюстрирует, как выполнить то, что вам нужно. Преимущество заключается в том, что выходные данные хранятся в потоке, который его сгенерировал, так что вы можете присоединиться и получить выходные данные каждого потока в любое время. При запуске скрипт печатает

Hi from thread #1
Hi from thread #2
Hi from thread #3
Hi from thread #4
Hi from thread #5
13
задан Deduplicator 9 March 2015 в 16:34
поделиться

1 ответ

Проблема в том, что std :: string компилируется как внутренний (не общедоступный) тип. Фактически это изменение в VS 2005+:

http://msdn.microsoft.com/en-us/library/ms177253 (VS.80) .aspx :

Собственные типы по умолчанию являются закрытыми вне собрания Собственные типы теперь по умолчанию не будут видны вне сборки. Дополнительные сведения о видимости типа за пределами сборки см. В разделе Видимость типа. Это изменение было вызвано в первую очередь потребностями разработчиков, использующих другие языки без учета регистра при обращении к метаданным, созданным в Visual C ++.

Вы можете подтвердить это с помощью Ildasm или отражателя , вы увидите, что ваш экстракт метод компилируется как:

public unsafe void Extract(basic_string<char,std::char_traits<char>,std::allocator<char> >* modopt(IsImplicitlyDereferenced) data_)

с базовой_строкой, компилируемой как:

[StructLayout(LayoutKind.Sequential, Size=0x20), NativeCppClass, MiscellaneousBits(0x40), DebugInfoInPDB, UnsafeValueType]
internal struct basic_string<char,std::char_traits<char>,std::allocator<char> >

Обратите внимание на внутренний .

К сожалению, в этом случае вы не можете вызвать такой метод из другой сборки.

В некоторых случаях доступен обходной путь: вы можете принудительно скомпилировать собственный тип как общедоступный с помощью прагмы make_public.

например, если у вас есть метод Extract2, например:

void Extract2( std::exception& data_ );

, вы можете принудительно использовать std :: исключение должно быть скомпилировано как общедоступное, предварительно включив этот оператор прагмы:

#pragma make_public(std::exception)

этот метод теперь доступен для всех сборок.

К сожалению, make_public не работает для шаблонных типов (std :: string просто является typedef для basic_string <>) Я не думаю, что вы можете что-то сделать, чтобы это сработало. Я рекомендую использовать управляемый тип System :: String ^ вместо этого во всех ваших общедоступных API. Это также гарантирует, что вашу библиотеку можно будет легко вызвать из других языков CLR, таких как C #

.
25
ответ дан 1 December 2019 в 20:11
поделиться
Другие вопросы по тегам:

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