私が見る限り、あなたのコードは MSDN のサンプルと同じはずです。ただし、Code が示すように、MSDN のサンプルは少し風変わりに見えます。実際、MSDN のサンプルが機能しているのは偶然にすぎないように思えます。
そのコードのコメントに次のように記載されていることに注意してください。
// EnumerateTraceGuids requires a valid pointer. Create a dummy
// allocation, so that you can get the actual allocation size.
pProviders
次に、1 つのポインターを格納するための領域を割り当てます。ただし、pProviders
実際には含まれる値が重要です。することはできませんNULL
。Delphi コードでは、実際にそのメモリを 2 回ゼロ化します。で一度AllocMem
、一度でZeroMemory
。Delphi コードを変更して 0 以外の内容を作成するとproviders
、Delphi コードが機能し始めます。
以下は、何が起こっているかを正確に示す非常に単純なプロジェクトです。
program _EnumerateTraceGuidsFaultDemo;
{$APPTYPE CONSOLE}
function EnumerateTraceGuids(
GuidPropertiesArray: Pointer;
PropertyArrayCount: Cardinal;
var GuidCount: Cardinal): Cardinal; stdcall; external 'advapi32.dll';
var
providers: Pointer;
providerCount: LongWord;
registeredProviderCount: LongWord;
res: LongWord;
begin
providerCount := 0;
registeredProviderCount := 0;
providers := AllocMem(SizeOf(Pointer));//zeroises memory
res := EnumerateTraceGuids(providers, providerCount, registeredProviderCount);
Writeln(res);//outputs 87
PInteger(providers)^ := 1;
res := EnumerateTraceGuids(providers, providerCount, registeredProviderCount);
Writeln(res);//outputs 234
Readln;
end.
それで問題は説明できると思いますが、実際にはそれよりも完全に解決したいと思います。あなたの作業の次のステップに進みEnumerateTraceGuids
、構造体に相当する実際の Delphi を使用して完全に宣言しますTRACE_GUID_PROPERTIES
。
私はおそらく次のようなコードを書くでしょう:
program _EnumerateTraceGuids;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, Windows;
type
PTraceGuidProperties = ^TTraceGuidProperties;
TTraceGuidProperties = record
Guid: TGUID;
GuidType: ULONG;
LoggerId: ULONG;
EnableLevel: ULONG;
EnableFlags: ULONG;
IsEnable: Boolean;
end;
function EnumerateTraceGuids(
var GuidPropertiesArray: PTraceGuidProperties;
PropertyArrayCount: ULONG;
var GuidCount: ULONG
): ULONG; stdcall; external 'advapi32.dll';
function GetRegisteredProviderCount: ULONG;
var
provider: TTraceGuidProperties;
pprovider: PTraceGuidProperties;
providerCount: LongWord;
registeredProviderCount: ULONG;
res: ULONG;
begin
providerCount := 0;
pprovider := @provider;
res := EnumerateTraceGuids(pprovider, providerCount, registeredProviderCount);
if (res<>ERROR_MORE_DATA) and (res<>ERROR_SUCCESS) then
RaiseLastOSError;
Result := registeredProviderCount;
end;
var
i: Integer;
provider: TTraceGuidProperties;
pprovider: PTraceGuidProperties;
providers: array of TTraceGuidProperties;
pproviders: array of PTraceGuidProperties;
providerCount: ULONG;
registeredProviderCount: ULONG;
res: ULONG;
begin
providerCount := GetRegisteredProviderCount;
SetLength(providers, providerCount);
SetLength(pproviders, providerCount);
for i := 0 to providerCount-1 do
pproviders[i] := @providers[i];
res := EnumerateTraceGuids(pproviders[0], providerCount, registeredProviderCount);
if res<>ERROR_SUCCESS then
RaiseLastOSError;
//do stuff with providers
end.
で可愛すぎようとするのではなくGetRegisteredProviderCount
、実際の へのポインタを渡しましたTRACE_GUID_PROPERTIES
。