Среда выполнения .Net обычно не выгружает ваши DLL-файлы pinvoke самостоятельно, так как не может знать, безопасно ли это делать, например, содержат ли они состояние, включая глобальные переменные, такие как статические строки или что-то подобное.
В вашем вопросе неясно, имеете ли вы в виду статическое на стороне .Net или статическое / постоянное на неуправляемой стороне. Если вы имеете в виду один на управляемой стороне, то он не гарантирован, чтобы существовать после возвращения вызова, если он был маршализован, и в зависимости от настройки для вызова на управляемой стороне, если вы не следуете некоторым очень определенным правилам. Если это просто номер плана, то это не имеет значения, поэтому я предполагаю, что это строка или какая-то более сложная структура.
Например, если вызываемый объект является функцией ac в dll, ожидающей строку ANSI, и вы позволяете pinvoke взять строку C #, она будет маршалировать строку Unicode C # в строку ASNI и будет ожидать получения вернуть эту память после завершения вызова, даже если эта строка пришла из статического C #. Даже если это не так, любой указатель на управляемую память следует считать недействительным после вызова, если только вы не закрепляете эту память.
Вот какая веревка, чтобы повеситься:) Используйте это с осторожностью. Это будет привязывать управляемую память на неопределенный срок, и я не рекомендую делать это. DLL, имеющая свою собственную копию строки, или управляемая сторона, имеющая свою собственную копию, не будет величайшим преступлением в области программирования, когда-либо совершенным. И с практической точки зрения было бы намного быстрее, если бы каждый из них имел по одному в своей куче, если бы он действительно был статичным. Функция C должна сделать свою собственную копию до возврата вызова.