То, что DLL делает внутри, не имеет значения, если речь идет о C #. Имейте в виду, что шаблоны C ++ не генерируют никакого кода, пока не будет создан экземпляр шаблона. Если шаблон просто определен где-то в заголовочных файлах DLL, то не будет никакого сгенерированного кода для этого шаблона в DLL. С другой стороны, если DLL явно создает и экспортирует некоторые шаблонные типы, то вы можете теоретически вызывать их из C #.
Есть две проблемы, которые вам нужно преодолеть. Во-первых, компиляторы C ++ манипулируют именами своих методов, поэтому вам нужно точно определить, какое имя PInvoke является правильным. Вторая проблема заключается в том, что нет возможности создавать объекты CRT непосредственно в C #. Вам нужно будет определить некоторые фабричные методы и экспортировать их.
Честно говоря, я думаю, что это намного больше проблем, чем стоит. Вам лучше создать API в стиле C для DLL и вызывать эти функции из C #. Внутри функции могут создавать и управлять соответствующими объектами C ++.