Hidlibrary: ReadReport() ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

์— ๋งŒ๋“  2011๋…„ 08์›” 14์ผ  ยท  9์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: mikeobrien/HidLibrary

ํ›Œ๋ฅญํ•œ ๋„์„œ๊ด€ Mike, ์ด ์—„์ฒญ๋‚œ ์ž‘์—…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” InputReport๋ฅผ ๋ฐ์ดํ„ฐ๋กœ ์ฑ„์šฐ๊ณ  ์‹ถ์„ ๋•Œ์ž…๋‹ˆ๋‹ค.

InputReport = device.ReadReport();

์—ฌ๊ธฐ์„œ InputReport๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

HidLibrary.HidReport InputReport = ์ƒˆ๋กœ์šด HidLibrary.HidReport(device.Capabilities.InputReportByteLength);

ํŠนํžˆ ์žฅ์น˜์—์„œ ๋น„๋™๊ธฐ ๋ชจ๋“œ๋กœ ๋ณด๊ณ ์„œ๋ฅผ ์ฝ์„ ๋•Œ(์˜ˆ: 1์ดˆ์— 100๋ฒˆ) ๋ˆ„์ถœ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋งค์šฐ ํฝ๋‹ˆ๋‹ค. ๋ช‡ ๋ถ„ ์•ˆ์— ์ˆ˜๋ฐฑ ๋ฉ”๊ฐ€๋ฐ”์ดํŠธ๊ฐ€ ์†Œ์š”๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” C# ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ดˆ๋ณด์ž์ด๋ฉฐ ์œ„์—์„œ ์„ค๋ช…ํ•œ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค ;(

์ธ์‚ฌ๋ง!

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‹ค์Œ์€ kaczart(๊ทธ๋ฆฌ๊ณ  ๋‚˜)๊ฐ€ ๋ฐœ๊ฒฌํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ œ์•ˆ๋œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
https://github.com/macaba/HidLibrary/commit/8f1864e1351ccca4772d5bbc18a0f94d7ba07fe7

์‚ฌ์šฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

device.ConnectionCheckOverride = device.IsConnected;
methodRequiringFasterUSBReadWrite();
device.ConnectionCheckOverride = false;

์ด๋กœ ์ธํ•ด ๋Œ€๋Ÿ‰ USB ์ „์†ก ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์‹คํ–‰ ์‹œ๊ฐ„์ด 159์ดˆ์—์„œ 47์ดˆ๋กœ ๋‹จ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

IsConnected ์†์„ฑ์ด HidDeviceEventMonitor์—์„œ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ํ˜„์žฌ ์—ฐ๊ฒฐ๋œ USB ์žฅ์น˜๋ฅผ ์—ด๊ฑฐํ•˜๋Š” ์›๋ž˜ ๊ธฐ๋Šฅ์„ ์œ ์ง€ํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜๋Š” kaczart์˜ ์†”๋ฃจ์…˜์— ๊ด€์‹ฌ์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ; ๋‚˜๋Š” Inserted ๋ฐ Removed ์ด๋ฒคํŠธ๊ฐ€ kaczart์˜ ์ฝ”๋“œ์—์„œ ํ˜ธ์ถœ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(๊ฐ„๋‹จํ•œ ์‚ดํŽด๋ณด๊ธฐ์—์„œ).

๋ชจ๋“  9 ๋Œ“๊ธ€

์นด์ฐจ๋ฅดํŠธ,

๋ถˆํ–‰ํžˆ๋„ ๊ทธ ์ฝ”๋“œ๋Š” ๊ฝค ์˜ค๋ž˜๋˜์—ˆ๊ณ  ๊ทธ๊ฒƒ์„ ์ค„ ์‹œ๊ฐ„์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค
๋ชจ๋“  TLC. ์ด ์‹œ์ ์—์„œ ๋‚˜๋Š” ๋‹จ์ง€ ๊ทธ๊ฒƒ์„ ์ฐธ์กฐ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์„ 
๋‚ด๊ธฐ๋Š” ํฌํฌ/๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฏธ๋””์—„

2011๋…„ 8์›” 14์ผ ์ผ์š”์ผ ์˜ค์ „ 10:37 kaczart <
๋‹ต์žฅ@reply.github.com>์ž‘์„ฑ:

ํ›Œ๋ฅญํ•œ ๋„์„œ๊ด€ Mike, ์ด ์—„์ฒญ๋‚œ ์ž‘์—…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” InputReport๋ฅผ ๋ฐ์ดํ„ฐ๋กœ ์ฑ„์šฐ๊ณ  ์‹ถ์„ ๋•Œ์ž…๋‹ˆ๋‹ค.

InputReport = device.ReadReport();

์—ฌ๊ธฐ์„œ InputReport๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

HidLibrary.HidReport InputReport = ์‹ ๊ทœ
HidLibrary.HidReport(ukp.Capabilities.InputReportByteLength);

ํŠนํžˆ ๋ณด๊ณ ์„œ๋ฅผ ๋น„๋™๊ธฐ์‹์œผ๋กœ ์ฝ์„ ๋•Œ ๋ˆ„์ถœ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋งค์šฐ ํฝ๋‹ˆ๋‹ค.
์žฅ์น˜์—์„œ ๋ชจ๋“œ(์˜ˆ: 1์ดˆ์— 100ํšŒ). ๋ช‡ ๋ถ„ ์•ˆ์— ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
์ˆ˜๋ฐฑ ๋ฉ”๊ฐ€ ๋ฐ”์ดํŠธ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.

์ €๋Š” C# ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ดˆ๋ณด์ž์ด๋ฉฐ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
์œ„์— ์„ค๋ช… ;(

์ธ์‚ฌ๋ง!

์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/mikeobrien/HidLibrary/issues/11

์นด์ฐจ๋ฅดํŠธ,

ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์œผ์…จ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋‹จ์ง€ ๊ฐ™์€ ๊ฒƒ์„ ๋ˆˆ์น˜ ์ฑ˜๋‹ค.
ํ›Œ๋ฅญํ•œ ๋„์„œ๊ด€ Mike, ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ €๋Š” Endicia USB ์Šค์ผ€์ผ๋กœ ์ž‘์—…ํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์ด๊ฒƒ์€ ๊ฝค ์žฌ๋ฏธ์žˆ์Šต๋‹ˆ๋‹ค.

jrockfl,

๋ถˆํ–‰ํžˆ๋„ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์‹œ๊ฐ„๊ณผ ๊ธฐ์ˆ ์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

์ธ์‚ฌ๋ง

๋ฌธ์ œ๋Š” HidReport ๋ฐ Devicedata๊ฐ€ ํ•ด์ œ๋˜์ง€ ์•Š์•„ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ฒ˜๋ฆฌ ํ›„ ํ•ด์ œํ•˜๋Š” ๊ฒƒ์€ ์‰ฌ์šด ์ˆ˜์ •์ด์ง€๋งŒ ...

๋งˆ์ง€๋ง‰์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ–ˆ์œผ๋ฉฐ ์ฐพ์€ ๋‚ด์šฉ์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

1) ์šฐ์„ , ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ชจ๋“  Read/Write ๋ฉ”์„œ๋“œ๋Š” ์žฅ์น˜๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. IsConnected ๋ฉ”์„œ๋“œ๊ฐ€ EnumerateHidDevices()๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ด ๋งŽ์ด ์†Œ๋ชจ๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์žฅ์น˜์—์„œ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ํŒจํ‚ค์ง€๋ฅผ ๋ณด๋‚ผ ๋•Œ PC ํ˜ธ์ŠคํŠธ๋Š” HID ์žฅ์น˜๋ณด๋‹ค ๋Š๋ฆฌ๊ณ  ์ œํ•œ๋œ ๋ง ๋ฒ„ํผ(๊ธฐ๋ณธ์ ์œผ๋กœ 32๊ฐœ ๋ณด๊ณ ์„œ, 512๊ฐœ๋กœ ํ™•์žฅ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ตœ์ข… ์†”๋ฃจ์…˜์€ ์•„๋‹˜)๋กœ ์ธํ•ด ์ผ๋ถ€ ํŒจํ‚ท์ด ์†์‹ค๋ฉ๋‹ˆ๋‹ค.
์ถ”์‹ . ๋‹ค์Œ์„ ํ˜ธ์ถœํ•˜์—ฌ ๋ง ๋ฒ„ํผ๋ฅผ 32๊ฐœ์—์„œ ์ตœ๋Œ€ 512๊ฐœ ๋ณด๊ณ ์„œ๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
NativeMethods .HidD_SetNumInputBuffers((int)device.ReadHandle, 512); // XP ์ด์ƒ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
2) ๋‘ ๋ฒˆ์งธ๋กœ EnumerateHidDevices()์—์„œ "yield return devicePath"๋กœ ์ธํ•ด ์—„์ฒญ๋‚œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. 69ํ–‰ ๋ฐ NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet); ์ ˆ๋Œ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚ด ์†”๋ฃจ์…˜:
1) ์ฝ๊ธฐ/์“ฐ๊ธฐ๋งˆ๋‹ค IsConnected๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. HidDevice์—์„œ ์ถ”๊ฐ€ isConnected ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
public bool isConnected;
์—ฐ๊ฒฐ์ด ์„ฑ๊ณตํ•œ ํ›„ ๋ณ€์ˆ˜๋ฅผ true๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: Connect() ํ•จ์ˆ˜์—์„œ):
device.isConnected = true;
๋ชจ๋“  DeviceEventMonitorInserted() ๋ฐ DeviceEventMonitorRemoved() ์ด๋ฒคํŠธ์—์„œ ์—…๋ฐ์ดํŠธํ•˜์‹ญ์‹œ์˜ค. ์˜ˆ:
if (์‚ฝ์ž… != null ) Inserted();
๋‹ค์Œ์œผ๋กœ ๋Œ€์ฒด:
if (์‚ฝ์ž… != null )
{
isConnected = ์ฐธ;
์‚ฝ์ž…();
}
๊ทธ๋ฆฌ๊ณ :
if (์ œ๊ฑฐ๋จ != null ) Removed();
๋‹ค์Œ์œผ๋กœ ๋Œ€์ฒด:
if (์ œ๊ฑฐ != null )
{
isConnected = ๊ฑฐ์ง“ ;
์ œ๊ฑฐ๋จ();
}
๋ชจ๋“  ์ฝ๊ธฐ/์“ฐ๊ธฐ ํ˜ธ์ถœ ๊ธฐ๋Šฅ์—์„œ ์ด ๋ณ€์ˆ˜๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค:
if(IsConnected) ๋Œ€์‹  if(isConnected)
์žฅ์น˜๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•  ๋•Œ๋งˆ๋‹ค ๊ณต์šฉ ๋ณ€์ˆ˜ isConnected์˜ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค - ์ฝ๊ธฐ ์Šค๋ ˆ๋“œ์˜ ๊ฒฝ์šฐ 10-20% ๋Œ€์‹  0-1% ํ”„๋กœ์„ธ์„œ ์‚ฌ์šฉ.

2) HidDevice.cs ์ค„ #69์—์„œ ๋‹ค์Œ์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
// ๋ฐ˜ํ™˜ devicePath๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
NativeMethods .SetupDiDestroyDeviceInfoList(deviceInfoSet); ์ ์ ˆํ•˜๊ฒŒ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
๋‹ค์Œ์œผ๋กœ NativeMethods .SetupDiDestroyDeviceInfoList(deviceInfoSet) ๋‹ค์Œ์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
foreach(์žฅ์น˜์˜ ๋ฌธ์ž์—ด devicePath)
๋ฐ˜ํ™˜ ์žฅ์น˜ ๊ฒฝ๋กœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
์—„์ฒญ๋‚œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ˆ˜์ •๋ฉ๋‹ˆ๋‹ค(์ œ ๊ฒฝ์šฐ์—๋Š” ์ˆ˜์‹  ๋ฐ์ดํ„ฐ 1MB๋‹น ์•ฝ 256MB).

๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ต‰์žฅํ•ฉ๋‹ˆ๋‹ค, ํžŒํŠธ๋ฅผ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, kaczart!!!

๋‹ค์Œ์€ kaczart(๊ทธ๋ฆฌ๊ณ  ๋‚˜)๊ฐ€ ๋ฐœ๊ฒฌํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ œ์•ˆ๋œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
https://github.com/macaba/HidLibrary/commit/8f1864e1351ccca4772d5bbc18a0f94d7ba07fe7

์‚ฌ์šฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

device.ConnectionCheckOverride = device.IsConnected;
methodRequiringFasterUSBReadWrite();
device.ConnectionCheckOverride = false;

์ด๋กœ ์ธํ•ด ๋Œ€๋Ÿ‰ USB ์ „์†ก ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์‹คํ–‰ ์‹œ๊ฐ„์ด 159์ดˆ์—์„œ 47์ดˆ๋กœ ๋‹จ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

IsConnected ์†์„ฑ์ด HidDeviceEventMonitor์—์„œ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ํ˜„์žฌ ์—ฐ๊ฒฐ๋œ USB ์žฅ์น˜๋ฅผ ์—ด๊ฑฐํ•˜๋Š” ์›๋ž˜ ๊ธฐ๋Šฅ์„ ์œ ์ง€ํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜๋Š” kaczart์˜ ์†”๋ฃจ์…˜์— ๊ด€์‹ฌ์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ; ๋‚˜๋Š” Inserted ๋ฐ Removed ์ด๋ฒคํŠธ๊ฐ€ kaczart์˜ ์ฝ”๋“œ์—์„œ ํ˜ธ์ถœ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(๊ฐ„๋‹จํ•œ ์‚ดํŽด๋ณด๊ธฐ์—์„œ).

๋ชจ๋“  ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ์—์„œ ์žฅ์น˜ ์—ฐ๊ฒฐ์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์€ ๊ณ ์ฃผํŒŒ์ˆ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ฃผ์š” ์„ฑ๋Šฅ ๋ณ‘๋ชฉ ํ˜„์ƒ์ž…๋‹ˆ๋‹ค. ์ œ ๊ฒฝ์šฐ์—๋Š” ์žฅ์น˜ ์—ฐ๊ฒฐ์„ ๋‹ค์‹œ ํ™•์ธํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์žฅ์น˜๊ฐ€ ์—ฐ๊ฒฐ๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋Š” ๊ฒƒ์ด 30๋ฐฐ ๋” ๋นจ๋ž์Šต๋‹ˆ๋‹ค. ์™•๋ณต ์‹œ๊ฐ„์€ ์•ฝ 70ms์—์„œ 2ms๋กœ ๋–จ์–ด์กŒ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋น ๋ฅธ ํ’€๋ง ์‚ฌ์šฉ์„ ์œ„ํ•ด ๋‚ด ์ž์‹ ์˜ IO๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ํ™•์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

        [DllImport("hid.dll", SetLastError = true)]
        static internal extern bool HidD_SetOutputReport(IntPtr hidDeviceObject, byte[] lpReportBuffer, int reportBufferLength);

        [DllImport("kernel32.dll", SetLastError = true)]
        static internal extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);
        public static bool FastWrite(this HidLibrary.HidDevice device, byte[] outputBuffer)
        {
            try
            {
                if (NativeMethods.HidD_SetOutputReport(device.Handle, outputBuffer, outputBuffer.Length))
                    return true;
                else
                    return false;
            }
            catch
            {
                return false;
            }
        }
        public static ReadStatus FastRead(this HidLibrary.HidDevice device, byte[] inputBuffer)
        {
            try
            {
                uint bytesRead;
                if (NativeMethods.ReadFile(device.Handle, inputBuffer, (uint)inputBuffer.Length, out bytesRead, IntPtr.Zero))
                {
                    return ReadStatus.Success;
                }
                else
                {
                    return ReadStatus.NoDataRead;
                }
            }
            catch (Exception)
            {
                return ReadStatus.ReadError;
            }
        }
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰