プログラムで、Windowsカラーマネージメントを設定して、ホビープロジェクトとしてf.luxのようなエフェクトをアーカイブしようとしました。Marshalクラスを使用してC#でポインタからメモリを読み込もうとしたとき
** WINAPI WcsGetDefaultColorProfileSize
の定義。 **
BOOL WINAPI WcsGetDefaultColorProfileSize(
_In_ WCS_PROFILE_MANAGEMENT_SCOPE profileManagementScope,
_In_opt_ PCWSTR pDeviceName,
_In_ COLORPROFILETYPE cptColorProfileType,
_In_ COLORPROFILESUBTYPE cpstColorProfileSubType,
_In_ DWORD dwProfileID,
_Out_ PDWORD pcbProfileName
);
**これは管理対象のWcsGetDefaultColorProfileSize
の署名です。 **
[DllImport("Mscms.dll", EntryPoint = "WcsGetDefaultColorProfileSize", CharSet = CharSet.Unicode)]
private static extern bool GetDefaultColorProfileSize(
WCS_PROFILE_MANAGEMENT_SCOPE profileManagementScope,
[MarshalAs(UnmanagedType.LPWStr), In] string pDeviceName,
COLORPROFILETYPE cptColorProfileType,
COLORPROFILESUBTYPE cpstColorProfileSubType,
Int32 dwProfileID,
out IntPtr pcbProfileSize
);
私はMarshalクラスを使用してWINAPIからポインタとしての復帰である文字列を取得しようとすると問題があります。 Marshal.ReadInt32
を使用して、この
// Need to get the size of ICC profile file first
GetDefaultColorProfileSize(
WCS_PROFILE_MANAGEMENT_SCOPE.WCS_PROFILE_MANAGEMENT_SCOPE_CURRENT_USER,
monitor_name.DeviceKey,
COLORPROFILETYPE.CPT_ICC,
COLORPROFILESUBTYPE.CPST_RGB_WORKING_SPACE,
1,
out SizePointer);
System.Diagnostics.Debug.WriteLine("Size is " + Marshal.ReadInt32(SizePointer));
GetDefaultColorProfileSize
リターンTRUE
が、私はそれが返すアドレスにアクセスしようとすると、(これは、このアドレス0x0000003eを返す)のようにそれは
System.AccessViolationExceptionを読み取ろうとしました。このエラーをスローまたは書き込み保護されたメモリ。これはしばしば、他のメモリが壊れていることを示します。
どのようにしてそのポインタのメモリを読み取ることができますか?
は私がIntPtr SizePointer = Marshal.AllocHGlobal(4);
にIntPtr SizePointer
から変更nvoigt
によって示唆された第1のメモリを割り当てようが、それはまだ完全なコードは、ここで以下の通りです同じ例外
を投げます。
Enumnerateのディスプレイデバイス
[DllImport("User32.dll")]
private static extern bool EnumDisplayDevices(
string lpDevice, int iDevNum,
ref DISPLAY_DEVICE lpDisplayDevice, int dwFlags);
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAY_DEVICE
{
public int cb;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceString;
public int StateFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string DeviceKey;
public DISPLAY_DEVICE(int flags) {
cb = 0;
StateFlags = flags;
DeviceName = new string((char)32, 32);
DeviceString = new string((char)32, 128);
DeviceID = new string((char)32, 128);
DeviceKey = new string((char)32, 128);
cb = Marshal.SizeOf(this);
}
}
ウィンドウの色システム
enum WCS_PROFILE_MANAGEMENT_SCOPE
{
WCS_PROFILE_MANAGEMENT_SCOPE_SYSTEM_WIDE = 0,
WCS_PROFILE_MANAGEMENT_SCOPE_CURRENT_USER
}
enum COLORPROFILETYPE
{
CPT_ICC = 0x0001,
CPT_DMP,
CPT_CAMP,
CPT_GMMP
}
enum COLORPROFILESUBTYPE
{
CPST_NONE = 0x0000,
CPST_RGB_WORKING_SPACE = 0x0001,
CPST_PERCEPTUAL = 0x0002,
CPST_ABSOLUTE_COLORIMETRIC = 0x0004,
CPST_RELATIVE_COLORIMETRIC = 0x0008,
CPST_SATURATION = 0x0010,
CPST_CUSTOM_WORKING_SPACE = 0x0020
}
[DllImport("Mscms.dll", EntryPoint = "WcsGetDefaultColorProfileSize", CharSet = CharSet.Unicode)]
private static extern bool GetDefaultColorProfileSize(
WCS_PROFILE_MANAGEMENT_SCOPE profileManagementScope,
[MarshalAs(UnmanagedType.LPWStr), In] string pDeviceName,
COLORPROFILETYPE cptColorProfileType,
COLORPROFILESUBTYPE cpstColorProfileSubType,
Int32 dwProfileID,
out IntPtr pcbProfileSize
);
[DllImport("Mscms.dll", EntryPoint = "WcsGetDefaultColorProfile" , CharSet =CharSet.Unicode, SetLastError =true)]
private unsafe static extern bool GetDefaultColorProfile(WCS_PROFILE_MANAGEMENT_SCOPE profileManagementScope,
[MarshalAs(UnmanagedType.LPWStr), In] string pDeviceName,
COLORPROFILETYPE cptColorProfileType,
COLORPROFILESUBTYPE cpstColorProfileSubType,
Int32 dwProfileID,
Int32 cbProfileName,
out IntPtr pProfileName);
[DllImport("Mscms.dll", EntryPoint = "WcsSetUsePerUserProfiles", CharSet = CharSet.Unicode)]
private static extern bool SetUsePerUserProfiles([MarshalAs(UnmanagedType.LPWStr), In]string pDeviceName, Int32 dwDeviceClass, bool usePerUserProfiles);
[DllImport("Mscms.dll", EntryPoint = "WcsGetUsePerUserProfiles", CharSet = CharSet.Unicode)]
private static extern bool GetUsePerUserProfiles([MarshalAs(UnmanagedType.LPWStr), In]string pDeviceName, Int32 dwDeviceClass, out bool pUsePerUserProfiles);
実際のコード
public unsafe static void GetProfile() {
DISPLAY_DEVICE lpDisplayDevice = new DISPLAY_DEVICE(0); // OUT
DISPLAY_DEVICE monitor_name = new DISPLAY_DEVICE(0); // OUT
int devNum = 0;
while (EnumDisplayDevices(null, devNum, ref lpDisplayDevice, 0)) {
int devNum2 = 0;
while (EnumDisplayDevices(lpDisplayDevice.DeviceName, devNum2, ref monitor_name, 0)) {
IntPtr SizePointer;
// Need to get the size of ICC profile file first
GetDefaultColorProfileSize(
WCS_PROFILE_MANAGEMENT_SCOPE.WCS_PROFILE_MANAGEMENT_SCOPE_CURRENT_USER,
monitor_name.DeviceKey,
COLORPROFILETYPE.CPT_ICC,
COLORPROFILESUBTYPE.CPST_RGB_WORKING_SPACE,
1,
out SizePointer);
System.Diagnostics.Debug.WriteLine("Size is " + Marshal.ReadInt32(SizePointer));
// Try to get a location of ICC profile file.
// Not Implement Yet
break;
}
break;
}
}
:
が後でそれを解放することを忘れないでください、これはごみ収集ではありません。 – Dennis
申し訳ありませんが、私は今質問を読みやすくするために修正しました。 – Suttisak