1. 개요
대부분의 프로젝트는 혼자서 만든 Application 프로젝트만 사용하는 것이 아니라 외부 참조를 사용하는 경우가 많다. 이 것이 .Net 프로젝트만 사용하면 모르겠지만 C++ native dll 파일을 참조하는 경우에는 더욱더 Platform Target 설정에 어려움을 겪을 때가 있다.
이런 상황들에 대해서 정리를 한다.
2. .Net Platform Traget 의 종류
.Net 프로젝트의 경우 Build 옵션을 보면 Platform Target을 지정하는 것이 있다.
이는 해당 프로젝트가 어떤 운영체에서 사용되기 위한 것인지를 지정하는 것이다.
x86과 x64의 경우는 설정이 매우 명확하다. 하지만 Any CPU?? 이것이 바로 궁금한 내용이다.
프로그램을 개발할 때에 모든 운영체제를 만족하는 프로그램을 만들고 싶은것이 개발자의 욕심? 욕망? 과도 같은데.. 이런 이유로 나도 Platform을 아무 이유없이 Any CPU로 설정을 해서 써왔다.
하지만, 여러개의 라이브러리 또는 Nuget package를 사용하고 그리고 native dll을 Interop 한 라이브러리를 함께 쓰면 이것은 나의 예상을 벗어나는 경우가 발생한다.
간략하게 정리하면 아래와 같다.
- x86 : 32비트 운영체제 시스템으로 실행되도록 한다. 즉 32bit library 만 사용한다.
- x64 : 64비트 운영체제 시스템으로 실행되도록 한다. 즉 64bit library 만 사용한다.
- Any CPU(MSIL) : 실행되는 운영체제의 비트에 맞춰서 구동한다. 32비트에서는 x86으로 64비트에서는 x64로 구동된다.
- Any CPU + Prefer 32-bit : Any CPU 와 같이 동작하지만, 참조하는 library 가 32bit와 64bit 가 있을 경우 32bit를 우선으로 하도록 한다. 이는 호환성 부분에서 32bit 에서만 동작하는 경우 즉 외부 참조 라이브러리가 32bit 일 경우에 반드시 들어가야 하는 옵션이다.
3. 라이브러리 구성에 따른 설정
우선 .Net 기반 라이브러리는 프로그램의 Platform Target을 맞춰주는 것이 제일 합리적일 것이다. 만약에 서로 간의 다른 Target을 갖는 라이브러리 일 경우에는 아래와 같은 경고 메시지를 만나게 된다.
뭐, warning 이니까 괜찮겠지?
나도 정확히는 모르지만, 메모리의 영역을 벗어나거나 데이터의 overflow가 발생하게 되면 그 동작은 장담할 수 없다.
그러므로 라이브러리를 참조 할 때는 Target 이 동일한 라이브러리를 쓰는 것을 목표로 한다.
그리고 Native 라이브러리가 32bit 지원만 가능한 경우에는 x86또는 Any CPU + Prefer 32-bit 옵션을 선택한다.
그렇지 않을 경우에 외부 참조되는 32bit 라이브러리는 로드되지 않고 내부적으로 Bad Image Format 에러가 발생한다.
두가지의 옵션중에서 호환성을 높이기 위해서는 AnyCPU + Prefer 32-bit 옵션을 선택하면 된다.
4. 라이브러리 로드 테스트
설정한 Platform 에서 라이브러리를 로드 사용할 수 있는지 먼저 확인하면 좋다.
static void Main(string[] args)
{
SetDllDirectory("path\");
string[] libList = new[]
{
"mylibarary.dll"
};
foreach (var s in libList)
{
var ptr = LoadLibrary(s);
if(ptr == IntPtr.Zero)
{
int error = Marshal.GetLastWin32Error();
Console.WriteLine($"Failed to load library: {s}, error code {error}");
}
else
{
Console.WriteLine("Success to load : " + s);
}
}
}
[DllImport("kernel32", SetLastError = true)]
static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll")]
static extern bool FreeLibrary(IntPtr hModule);
// Dll 파일을 검색하는 Root directory 설정.
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetDllDirectory(string lpPathName);
}
ChatGPT 물어보기
what is the purpose of build option 'Prefer 32-bit' in visual studio .net?
The "Prefer 32-bit" option in Visual Studio .NET is used to specify whether the application should run in 32-bit mode or 64-bit mode on a 64-bit operating system. When this option is enabled, the application runs in 32-bit mode even on a 64-bit operating system.
The purpose of this option is to ensure compatibility with older 32-bit applications that may not function correctly in a 64-bit environment. By running in 32-bit mode, the application can use 32-bit system libraries and APIs, which may be required for proper functionality.
It's important to note that running in 32-bit mode may limit the application's ability to access large amounts of memory and take advantage of certain 64-bit features. Therefore, this option should only be used when necessary to maintain compatibility with older systems or libraries.
In summary, the "Prefer 32-bit" option in Visual Studio .NET is used to ensure compatibility with older 32-bit applications and should be used only when required for compatibility purposes.
Richard Bang
why is it not available to change in dll project?
The "Prefer 32-bit" option is not available in DLL (Dynamic Link Library) projects in Visual Studio because the setting only applies to the executable file that launches the process. DLLs are loaded into the process by the executable file, and they inherit the bitness (32-bit or 64-bit) of the process that loaded them.
In other words, the bitness of a DLL is determined by the bitness of the process that loads it, not by the bitness of the DLL project itself. Therefore, setting the "Prefer 32-bit" option in a DLL project would have no effect on the bitness of the DLL.
The "Prefer 32-bit" option is only applicable to EXE (executable) projects because the EXE file is the entry point for the process and determines its bitness. When the "Prefer 32-bit" option is enabled in an EXE project, the process will always run in 32-bit mode, even if the underlying operating system is 64-bit.
In summary, the "Prefer 32-bit" option is not available in DLL projects because DLLs inherit the bitness of the process that loads them, and the "Prefer 32-bit" option only applies to the executable file that launches the process.
Richard Bang
For application project, why is the option necessary even though threre is selection of x86 for platform target. could you compare the scenario between any cpu with prefer 32-bit option and just x86?
In Visual Studio, the "Prefer 32-bit" option is available even for application projects that have the x86 platform target selected. This is because the x86 platform target only ensures that the application will run in 32-bit mode on both 32-bit and 64-bit operating systems, but it does not guarantee that the application will use 32-bit system libraries and APIs.
When the "Prefer 32-bit" option is enabled, the application will be compiled to use 32-bit system libraries and APIs, even on a 64-bit operating system. This can be useful in certain scenarios, such as when the application depends on third-party libraries or APIs that are only available in 32-bit mode.
On the other hand, when the "Prefer 32-bit" option is not enabled and the x86 platform target is selected, the application will still run in 32-bit mode on both 32-bit and 64-bit operating systems, but it may use 64-bit system libraries and APIs when they are available. This can lead to compatibility issues if the application depends on third-party libraries or APIs that are only available in 32-bit mode.
To summarize, the "Prefer 32-bit" option ensures that the application will use 32-bit system libraries and APIs, even on a 64-bit operating system. This can be useful in certain scenarios, but it may limit the application's ability to access large amounts of memory and take advantage of certain 64-bit features. On the other hand, selecting the x86 platform target without the "Prefer 32-bit" option may result in the application using 64-bit system libraries and APIs, which can lead to compatibility issues in certain scenarios.
Richard Bang
what is the object to select platform target with x86 event though the application will be executed on 64bit os.
Selecting the x86 platform target in an application project ensures that the application will run as a 32-bit process on both 32-bit and 64-bit versions of Windows, even if the underlying operating system is 64-bit. This can be useful in several scenarios, including:
Compatibility: Some applications, particularly older ones, were designed to run in a 32-bit environment and may not function correctly in a 64-bit environment. Selecting the x86 platform target can ensure that these applications will run as intended, regardless of the operating system.
Interoperability: If the application needs to interact with other 32-bit components, such as third-party libraries or APIs, selecting the x86 platform target can ensure that there are no compatibility issues.
Performance: While 64-bit systems can provide better performance for certain applications, there are some cases where running as a 32-bit process may be more efficient. For example, if the application doesn't require access to more than 4GB of memory, running as a 32-bit process can reduce memory overhead and improve performance.
It's important to note that selecting the x86 platform target does not necessarily mean that the application will run more slowly or perform poorly on a 64-bit operating system. In fact, in some cases, running as a 32-bit process can improve performance and efficiency.
In summary, selecting the x86 platform target in an application project ensures that the application will run as a 32-bit process on both 32-bit and 64-bit versions of Windows, which can be useful for compatibility, interoperability, and performance reasons.
Richard Bang
what about x64?
Selecting the x64 platform target in an application project ensures that the application will run as a 64-bit process on 64-bit versions of Windows, while it will not run on 32-bit versions of Windows. This can be useful in several scenarios, including:
Performance: 64-bit systems can provide better performance for certain applications, particularly those that require access to large amounts of memory. Running as a 64-bit process allows the application to address more than 4GB of memory, which can improve performance in memory-intensive applications.
Compatibility: If the application requires access to 64-bit system libraries or APIs, selecting the x64 platform target is necessary to ensure compatibility. For example, if the application requires access to the 64-bit version of a system database driver, selecting the x64 platform target is necessary.
Specific features: Some features or functionality may only be available in 64-bit mode, and selecting the x64 platform target may be necessary to take advantage of those features. For example, if the application requires access to 64-bit hardware drivers or other low-level system components, selecting the x64 platform target may be necessary.
It's important to note that selecting the x64 platform target may not be appropriate for all applications. If the application does not require access to large amounts of memory or specific 64-bit features, running as a 32-bit process may be more efficient and provide better performance.
In summary, selecting the x64 platform target in an application project ensures that the application will run as a 64-bit process on 64-bit versions of Windows, which can provide better performance and access to specific features. However, it's important to evaluate the application's requirements and determine whether running as a 32-bit process may be more appropriate.
Richard Bang
what about any cpu?
Selecting the Any CPU platform target in an application project allows the application to run as either a 32-bit or a 64-bit process, depending on the underlying operating system. Specifically, if the operating system is 32-bit, the application will run as a 32-bit process, and if the operating system is 64-bit, the application will run as a 64-bit process.
This can be useful in several scenarios, including:
Compatibility: If the application is designed to be compatible with both 32-bit and 64-bit operating systems, selecting the Any CPU platform target ensures that the application can run on either platform without modification.
Future-proofing: If the application is designed to have a long lifespan, selecting the Any CPU platform target can ensure that the application will continue to function as expected on future versions of Windows, which may use different architectures.
Simplifying deployment: Selecting the Any CPU platform target can simplify deployment, as there is no need to create separate builds for 32-bit and 64-bit platforms.
However, it's important to note that selecting the Any CPU platform target may not always be appropriate for all applications. For example, if the application requires access to specific 32-bit or 64-bit system libraries or APIs, or if the application is memory-intensive and requires access to more than 4GB of memory, selecting the appropriate x86 or x64 platform target may be necessary.
In summary, selecting the Any CPU platform target in an application project allows the application to run as either a 32-bit or a 64-bit process, which can be useful for compatibility, future-proofing, and simplifying deployment. However, it's important to evaluate the application's requirements and determine whether selecting the appropriate x86 or x64 platform target may be necessary.
Richard Bang
i want your confirmation that selecting target x86 might be possible to load x64 library in 64bit os like you mentioned above.
No, selecting the x86 platform target will not allow an application to load a 64-bit library on a 64-bit operating system. If an application is built as an x86 application, it can only load x86 libraries and not x64 libraries.
In order to load a 64-bit library, the application must be built as an x64 application. If the application is built as an Any CPU application, it will automatically load the appropriate version of the library based on the architecture of the operating system.
So, if you need to load a 64-bit library in a 64-bit operating system, you should build your application as an x64 application. However, if you do not have a specific need to use 64-bit libraries, building your application as an Any CPU or x86 application may be more appropriate.
Richard Bang
so what is the meaning your saying.
'In Visual Studio, the "Prefer 32-bit" option is available even for application projects that have the x86 platform target selected. This is because the x86 platform target only ensures that the application will run in 32-bit mode on both 32-bit and 64-bit operating systems, but it does not guarantee that the application will use 32-bit system libraries and APIs.'
I apologize for any confusion my previous response may have caused. The statement you quoted is not correct.
In Visual Studio, the "Prefer 32-bit" option is only available for application projects that have the "Any CPU" platform target selected. This option is not available for application projects that have the x86 platform target selected.
When an application is built with the x86 platform target, it will only run in 32-bit mode on both 32-bit and 64-bit operating systems, and it will use 32-bit system libraries and APIs. It is not possible to load 64-bit libraries in an x86 application, regardless of the operating system.
I hope this clears up any confusion, and please let me know if you have any further questions.
Richard Bang
So, i need to use 32bit native dll, what option is prefered? Any cpu with prefer 32bit and x86?
If you need to use a 32-bit native DLL, both the "Any CPU" platform target with the "Prefer 32-bit" option and the "x86" platform target will work. However, the "Any CPU" platform target with the "Prefer 32-bit" option is often the preferred option, because it provides more flexibility and compatibility.
When you select the "Any CPU" platform target with the "Prefer 32-bit" option, the application will run in 32-bit mode on both 32-bit and 64-bit operating systems, and it will prefer to load 32-bit versions of system libraries and APIs. This means that the application will work correctly with both 32-bit and 64-bit operating systems, and it will also be compatible with other 32-bit components that may be used by the application.
On the other hand, when you select the "x86" platform target, the application will always run in 32-bit mode, regardless of the underlying operating system. This can be a problem if the application needs to access 64-bit system libraries or APIs, or if it needs to access more than 4GB of memory.
So, if you need to use a 32-bit native DLL, the "Any CPU" platform target with the "Prefer 32-bit" option is often the best choice, because it provides more flexibility and compatibility. However, if you have a specific reason to always run the application in 32-bit mode, the "x86" platform target may be appropriate.
Richard Bang
With Any cpu with prefer 32bit, the application can use 32bit library and 64bit library based on their compatibility?
When an application is built with the "Any CPU" platform target and the "Prefer 32-bit" option, it will run as a 32-bit process on both 32-bit and 64-bit versions of Windows, and it will prefer to load 32-bit versions of system libraries and APIs. This means that the application can use both 32-bit and 64-bit libraries, but it will prefer to use the 32-bit versions of the libraries, if they are available and compatible.
In most cases, the application will be able to use 32-bit versions of the libraries, even on a 64-bit version of Windows. This is because 32-bit libraries can be loaded and executed in a 32-bit process, even on a 64-bit version of Windows. However, there may be some cases where the 32-bit library is not compatible with the 64-bit version of Windows, or where a 64-bit version of a library may be required for performance reasons or to access additional features.
In these cases, the application can still use the 64-bit version of the library, but it will need to ensure that the library is loaded and executed in a separate 64-bit process, rather than in the main 32-bit process. This can be done using techniques such as inter-process communication (IPC) or by creating a separate 64-bit process to host the library.
Overall, the "Any CPU" platform target with the "Prefer 32-bit" option provides a good balance of compatibility and performance, and it allows the application to use both 32-bit and 64-bit libraries as needed.