OCT 1. 初始化工程项目
This commit is contained in:
parent
13289dec0a
commit
28efa76d52
|
@ -0,0 +1,220 @@
|
|||
# ClangFormatConfigureSource: 'clang-format-file://D:/development/c/daemon_agent/.clang-format'
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
InsertBraces: true
|
||||
AlignArrayOfStructures: Left
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: true
|
||||
AcrossComments: true
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: true
|
||||
PadOperators: true
|
||||
AlignCompound: true
|
||||
AlignConsecutiveBitFields: None
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: true
|
||||
PadOperators: true
|
||||
AlignCompound: true
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: DontAlign
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
- __unused
|
||||
BinPackArguments: true
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: true
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: true
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^<ext/.*\.h>'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^<.*\.h>'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentCaseLabels: true
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentRequiresClause: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertTrailingCommas: None
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Never
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 1000
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 140
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Right
|
||||
RawStringFormats:
|
||||
- Language: Cpp
|
||||
Delimiters:
|
||||
- cc
|
||||
- CC
|
||||
- cpp
|
||||
- Cpp
|
||||
- CPP
|
||||
- 'c++'
|
||||
- 'C++'
|
||||
CanonicalDelimiter: ''
|
||||
BasedOnStyle: google
|
||||
- Language: TextProto
|
||||
Delimiters:
|
||||
- pb
|
||||
- PB
|
||||
- proto
|
||||
- PROTO
|
||||
EnclosingFunctions:
|
||||
- EqualsProto
|
||||
- EquivToProto
|
||||
- PARSE_PARTIAL_TEXT_PROTO
|
||||
- PARSE_TEST_PROTO
|
||||
- PARSE_TEXT_PROTO
|
||||
- ParseTextOrDie
|
||||
- ParseTextProtoOrDie
|
||||
- ParseTestProto
|
||||
- ParsePartialTestProto
|
||||
CanonicalDelimiter: ''
|
||||
BasedOnStyle: google
|
||||
ReflowComments: false
|
||||
SortIncludes: Never
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 4
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
BitFieldColonSpacing: Both
|
||||
Standard: Auto
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
SeparateDefinitionBlocks: Always
|
||||
WhitespaceSensitiveMacros:
|
||||
- STRINGIZE
|
||||
- PP_STRINGIZE
|
||||
- BOOST_PP_STRINGIZE
|
||||
- NS_SWIFT_NAME
|
||||
- CF_SWIFT_NAME
|
||||
TypenameMacros:
|
||||
- CONFIG_ITEM
|
||||
- PCONFIG_ITEM
|
|
@ -0,0 +1,5 @@
|
|||
################################################################################
|
||||
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
|
||||
################################################################################
|
||||
|
||||
/.vs
|
|
@ -0,0 +1,9 @@
|
|||
<Application x:Class="NetTunnelApp.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:NetTunnelApp"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace NetTunnelApp
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
|
@ -0,0 +1,13 @@
|
|||
<Window x:Class="NetTunnelApp.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:NetTunnelApp"
|
||||
mc:Ignorable="d"
|
||||
Title="NetTunnel" Height="450" Width="800" WindowStyle="ThreeDBorderWindow">
|
||||
<Grid>
|
||||
<Button Content="Button" HorizontalAlignment="Left" Margin="166,170,0,0" VerticalAlignment="Top" Height="47"
|
||||
Width="96" Click="Button_Click" />
|
||||
</Grid>
|
||||
</Window>
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NetTunnelApp
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
string path = System.Environment.CurrentDirectory + "\\tunnelsdk.log";
|
||||
NetTunnelLib.InitTunnelSDKLog(path, LogLevel.LOG_DEBUG);
|
||||
//IntPtr msg = TestMessage();
|
||||
//MessageBox.Show(Marshal.PtrToStringAnsi(msg));
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MessageBox.Show(NetTunnelLib.SetProtocolEncryptType(ProtoCryptoType.CRYPTO_NONE, "").ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<BaseOutputPath>C:\Users\HuangXin\Documents\development\visual_studio\NetworkTunnel\x64</BaseOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Update="App.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="MainWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NetTunnelApp;
|
||||
|
||||
public enum ProtoCryptoType
|
||||
{
|
||||
CRYPTO_NONE = 0,
|
||||
CRYPTO_BASE64 = 1,
|
||||
CRYPTO_AES128 = 2,
|
||||
CRYPTO_3DES = 3,
|
||||
CRYPTO_AES256 = 4
|
||||
}
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
LOG_DEBUG = 0,
|
||||
LOG_INFO = 1,
|
||||
LOG_WARN = 2,
|
||||
LOG_ERROR = 3
|
||||
}
|
||||
|
||||
public class NetTunnelLib
|
||||
{
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int CreateTunnel(String lpszMsg);
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr TestMessage();
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern Int32 Add(int a, int b);
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int TunnelSDKInitEnv();
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SetProtocolEncryptType(ProtoCryptoType type, String pProKey);
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void InitTunnelSDKLog(String pProKey, LogLevel level);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
|
|
@ -0,0 +1,71 @@
|
|||
#pragma checksum "..\..\..\App.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "A1E62818D7EBB48AC5E8E76F6BAC2BCA050E3CFF"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using NetTunnelApp;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NetTunnelApp {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// App
|
||||
/// </summary>
|
||||
public partial class App : System.Windows.Application {
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.7.0")]
|
||||
public void InitializeComponent() {
|
||||
|
||||
#line 5 "..\..\..\App.xaml"
|
||||
this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Application Entry Point.
|
||||
/// </summary>
|
||||
[System.STAThreadAttribute()]
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.7.0")]
|
||||
public static void Main() {
|
||||
NetTunnelApp.App app = new NetTunnelApp.App();
|
||||
app.InitializeComponent();
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
#pragma checksum "..\..\..\App.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "A1E62818D7EBB48AC5E8E76F6BAC2BCA050E3CFF"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using NetTunnelApp;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NetTunnelApp {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// App
|
||||
/// </summary>
|
||||
public partial class App : System.Windows.Application {
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.7.0")]
|
||||
public void InitializeComponent() {
|
||||
|
||||
#line 5 "..\..\..\App.xaml"
|
||||
this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Application Entry Point.
|
||||
/// </summary>
|
||||
[System.STAThreadAttribute()]
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.7.0")]
|
||||
public static void Main() {
|
||||
NetTunnelApp.App app = new NetTunnelApp.App();
|
||||
app.InitializeComponent();
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#pragma checksum "..\..\..\MainWindow.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "0F29C786CDED2A9EB262D4A59AC422C522507B21"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using NetTunnelApp;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NetTunnelApp {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// MainWindow
|
||||
/// </summary>
|
||||
public partial class MainWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector {
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.7.0")]
|
||||
public void InitializeComponent() {
|
||||
if (_contentLoaded) {
|
||||
return;
|
||||
}
|
||||
_contentLoaded = true;
|
||||
System.Uri resourceLocater = new System.Uri("/NetTunnelApp;component/mainwindow.xaml", System.UriKind.Relative);
|
||||
|
||||
#line 1 "..\..\..\MainWindow.xaml"
|
||||
System.Windows.Application.LoadComponent(this, resourceLocater);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.7.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
|
||||
#line 11 "..\..\..\MainWindow.xaml"
|
||||
((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.Button_Click);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
return;
|
||||
}
|
||||
this._contentLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#pragma checksum "..\..\..\MainWindow.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "0F29C786CDED2A9EB262D4A59AC422C522507B21"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using NetTunnelApp;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NetTunnelApp {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// MainWindow
|
||||
/// </summary>
|
||||
public partial class MainWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector {
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.7.0")]
|
||||
public void InitializeComponent() {
|
||||
if (_contentLoaded) {
|
||||
return;
|
||||
}
|
||||
_contentLoaded = true;
|
||||
System.Uri resourceLocater = new System.Uri("/NetTunnelApp;component/mainwindow.xaml", System.UriKind.Relative);
|
||||
|
||||
#line 1 "..\..\..\MainWindow.xaml"
|
||||
System.Windows.Application.LoadComponent(this, resourceLocater);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.7.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
|
||||
#line 11 "..\..\..\MainWindow.xaml"
|
||||
((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.Button_Click);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
return;
|
||||
}
|
||||
this._contentLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("NetTunnelApp")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("NetTunnelApp")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("NetTunnelApp")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")]
|
||||
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
|
||||
|
||||
// 由 MSBuild WriteCodeFragment 类生成。
|
||||
|
|
@ -0,0 +1 @@
|
|||
a5e6a2f249466fbbff4e1ac5541eb864cdca1db1
|
|
@ -0,0 +1,11 @@
|
|||
is_global = true
|
||||
build_property.TargetFramework = net6.0-windows
|
||||
build_property.TargetPlatformMinVersion = 7.0
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = NetTunnelApp
|
||||
build_property.ProjectDir = C:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\NetTunnelApp\
|
Binary file not shown.
|
@ -0,0 +1,20 @@
|
|||
NetTunnelApp
|
||||
|
||||
|
||||
winexe
|
||||
C#
|
||||
.cs
|
||||
C:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\NetTunnelApp\obj\Debug\net6.0-windows\
|
||||
NetTunnelApp
|
||||
none
|
||||
false
|
||||
TRACE;DEBUG;NET;NET6_0;NETCOREAPP
|
||||
C:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\NetTunnelApp\App.xaml
|
||||
11407045341
|
||||
|
||||
4-1392306876
|
||||
1941675070116
|
||||
MainWindow.xaml;
|
||||
|
||||
True
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
NetTunnelApp
|
||||
1.0.0.0
|
||||
|
||||
winexe
|
||||
C#
|
||||
.cs
|
||||
C:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\NetTunnelApp\obj\Debug\net6.0-windows\
|
||||
NetTunnelApp
|
||||
none
|
||||
false
|
||||
TRACE;DEBUG;NET;NET6_0;NETCOREAPP
|
||||
C:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\NetTunnelApp\App.xaml
|
||||
11407045341
|
||||
|
||||
6745177533
|
||||
1941675070116
|
||||
MainWindow.xaml;
|
||||
|
||||
True
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
|
||||
FC:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\NetTunnelApp\MainWindow.xaml;;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
|
||||
FC:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\NetTunnelApp\MainWindow.xaml;;
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// NetTunnelDemo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include "../NetTunnelSDK/tunnel.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Hello World!\n";
|
||||
std::cout << TunnelSDKInitEnv();
|
||||
}
|
||||
|
||||
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
|
||||
// 调试程序: F5 或调试 >“开始调试”菜单
|
||||
|
||||
// 入门使用技巧:
|
||||
// 1. 使用解决方案资源管理器窗口添加/管理文件
|
||||
// 2. 使用团队资源管理器窗口连接到源代码管理
|
||||
// 3. 使用输出窗口查看生成输出和其他消息
|
||||
// 4. 使用错误列表窗口查看错误
|
||||
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
|
||||
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
|
|
@ -0,0 +1,140 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{7cca5020-1e98-4aef-99a4-34c05592cfe1}</ProjectGuid>
|
||||
<RootNamespace>NetTunnelDemo</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="NetTunnelDemo.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NetTunnelSDK\NetTunnelSDK.vcxproj">
|
||||
<Project>{42aacc62-a37c-4b33-a687-d13c472cc980}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="NetTunnelDemo.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
|
@ -0,0 +1,186 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.1.0.0\build\native\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.props" Condition="Exists('..\packages\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.1.0.0\build\native\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.props')" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{42aacc62-a37c-4b33-a687-d13c472cc980}</ProjectGuid>
|
||||
<RootNamespace>NetTunnelSDK</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;NETTUNNELSDK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;NETTUNNELSDK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;NETTUNNELSDK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy $(OutDir)$(TargetName)$(TargetExt) $(OutDir)net6.0-windows /y
|
||||
copy $(OutDir)fmtd.dll $(OutDir)net6.0-windows /y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;NETTUNNELSDK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="logs\fmtlog-inl.h" />
|
||||
<ClInclude Include="logs\fmtlog.h" />
|
||||
<ClInclude Include="misc.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="tunnel.h" />
|
||||
<ClInclude Include="usrerr.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="logs\fmtlog.cc">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tunnel.cpp" />
|
||||
<ClCompile Include="usrerr.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.1.0.0\build\native\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.targets" Condition="Exists('..\packages\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.1.0.0\build\native\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.1.0.0\build\native\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.1.0.0\build\native\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.props'))" />
|
||||
<Error Condition="!Exists('..\packages\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.1.0.0\build\native\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.1.0.0\build\native\vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件\tunnel">
|
||||
<UniqueIdentifier>{b280dda3-87fc-4338-9b3d-2d3aac834993}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\tunnel">
|
||||
<UniqueIdentifier>{887650f6-e4f9-49ee-9314-9e4244cd63a5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="头文件\log">
|
||||
<UniqueIdentifier>{eebf9d26-4829-4879-8a09-a84ab879607e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\logs">
|
||||
<UniqueIdentifier>{879be0d2-53a0-4003-bdb8-449de0caad96}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="tunnel.h">
|
||||
<Filter>头文件\tunnel</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="logs\fmtlog.h">
|
||||
<Filter>头文件\log</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="logs\fmtlog-inl.h">
|
||||
<Filter>头文件\log</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="usrerr.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="misc.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tunnel.cpp">
|
||||
<Filter>源文件\tunnel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="logs\fmtlog.cc">
|
||||
<Filter>源文件\logs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="usrerr.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
|
@ -0,0 +1,16 @@
|
|||
// dllmain.cpp : 定义 DLL 应用程序的入口点。
|
||||
#include "pch.h"
|
||||
|
||||
#include "logs/fmtlog.h"
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
fmtlog::poll();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
|
||||
// Windows 头文件
|
||||
#include <windows.h>
|
|
@ -0,0 +1,636 @@
|
|||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Meng Rao <raomeng1@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#pragma warning( disable : 4996)
|
||||
#include "fmtlog.h"
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <limits>
|
||||
#include <ios>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <processthreadsapi.h>
|
||||
#else
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
void fmtlogEmptyFun(void*) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template<int ___ = 0>
|
||||
class fmtlogDetailT
|
||||
{
|
||||
public:
|
||||
// https://github.com/MengRao/str
|
||||
template<size_t SIZE>
|
||||
class Str
|
||||
{
|
||||
public:
|
||||
static const int Size = SIZE;
|
||||
char s[SIZE];
|
||||
|
||||
Str() {}
|
||||
Str(const char* p) { *this = *(const Str<SIZE>*)p; }
|
||||
|
||||
char& operator[](int i) { return s[i]; }
|
||||
char operator[](int i) const { return s[i]; }
|
||||
|
||||
template<typename T>
|
||||
void fromi(T num) {
|
||||
if constexpr (Size & 1) {
|
||||
s[Size - 1] = '0' + (num % 10);
|
||||
num /= 10;
|
||||
}
|
||||
switch (Size & -2) {
|
||||
case 18: *(uint16_t*)(s + 16) = *(uint16_t*)(digit_pairs + ((num % 100) << 1)); num /= 100;
|
||||
case 16: *(uint16_t*)(s + 14) = *(uint16_t*)(digit_pairs + ((num % 100) << 1)); num /= 100;
|
||||
case 14: *(uint16_t*)(s + 12) = *(uint16_t*)(digit_pairs + ((num % 100) << 1)); num /= 100;
|
||||
case 12: *(uint16_t*)(s + 10) = *(uint16_t*)(digit_pairs + ((num % 100) << 1)); num /= 100;
|
||||
case 10: *(uint16_t*)(s + 8) = *(uint16_t*)(digit_pairs + ((num % 100) << 1)); num /= 100;
|
||||
case 8: *(uint16_t*)(s + 6) = *(uint16_t*)(digit_pairs + ((num % 100) << 1)); num /= 100;
|
||||
case 6: *(uint16_t*)(s + 4) = *(uint16_t*)(digit_pairs + ((num % 100) << 1)); num /= 100;
|
||||
case 4: *(uint16_t*)(s + 2) = *(uint16_t*)(digit_pairs + ((num % 100) << 1)); num /= 100;
|
||||
case 2: *(uint16_t*)(s + 0) = *(uint16_t*)(digit_pairs + ((num % 100) << 1)); num /= 100;
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr const char* digit_pairs = "00010203040506070809"
|
||||
"10111213141516171819"
|
||||
"20212223242526272829"
|
||||
"30313233343536373839"
|
||||
"40414243444546474849"
|
||||
"50515253545556575859"
|
||||
"60616263646566676869"
|
||||
"70717273747576777879"
|
||||
"80818283848586878889"
|
||||
"90919293949596979899";
|
||||
};
|
||||
|
||||
fmtlogDetailT()
|
||||
: flushDelay(3000000000) {
|
||||
args.reserve(4096);
|
||||
args.resize(parttenArgSize);
|
||||
|
||||
fmtlogWrapper<>::impl.init();
|
||||
resetDate();
|
||||
fmtlog::setLogFile(stdout);
|
||||
setHeaderPattern("{HMSf} {s:<16} {l}[{t:<6}] ");
|
||||
logInfos.reserve(32);
|
||||
bgLogInfos.reserve(128);
|
||||
bgLogInfos.emplace_back(nullptr, nullptr, fmtlog::DBG, fmt::string_view());
|
||||
bgLogInfos.emplace_back(nullptr, nullptr, fmtlog::INF, fmt::string_view());
|
||||
bgLogInfos.emplace_back(nullptr, nullptr, fmtlog::WRN, fmt::string_view());
|
||||
bgLogInfos.emplace_back(nullptr, nullptr, fmtlog::ERR, fmt::string_view());
|
||||
threadBuffers.reserve(8);
|
||||
bgThreadBuffers.reserve(8);
|
||||
memset(membuf.data(), 0, membuf.capacity());
|
||||
}
|
||||
|
||||
~fmtlogDetailT() {
|
||||
stopPollingThread();
|
||||
poll(true);
|
||||
closeLogFile();
|
||||
}
|
||||
|
||||
void setHeaderPattern(const char* pattern) {
|
||||
if (shouldDeallocateHeader) delete[] headerPattern.data();
|
||||
using namespace fmt::literals;
|
||||
for (int i = 0; i < parttenArgSize; i++) {
|
||||
reorderIdx[i] = parttenArgSize - 1;
|
||||
}
|
||||
headerPattern = fmtlog::unNameFormat<true>(
|
||||
pattern, reorderIdx, "a"_a = "", "b"_a = "", "C"_a = "", "Y"_a = "", "m"_a = "", "d"_a = "",
|
||||
"t"_a = "thread name", "F"_a = "", "f"_a = "", "e"_a = "", "S"_a = "", "M"_a = "", "H"_a = "",
|
||||
"l"_a = fmtlog::LogLevel(), "s"_a = "fmtlog.cc:123", "g"_a = "/home/raomeng/fmtlog/fmtlog.cc:123", "Ymd"_a = "",
|
||||
"HMS"_a = "", "HMSe"_a = "", "HMSf"_a = "", "HMSF"_a = "", "YmdHMS"_a = "", "YmdHMSe"_a = "", "YmdHMSf"_a = "",
|
||||
"YmdHMSF"_a = "");
|
||||
shouldDeallocateHeader = headerPattern.data() != pattern;
|
||||
|
||||
setArg<0>(fmt::string_view(weekdayName.s, 3));
|
||||
setArg<1>(fmt::string_view(monthName.s, 3));
|
||||
setArg<2>(fmt::string_view(&year[2], 2));
|
||||
setArg<3>(fmt::string_view(year.s, 4));
|
||||
setArg<4>(fmt::string_view(month.s, 2));
|
||||
setArg<5>(fmt::string_view(day.s, 2));
|
||||
setArg<6>(fmt::string_view());
|
||||
setArg<7>(fmt::string_view(nanosecond.s, 9));
|
||||
setArg<8>(fmt::string_view(nanosecond.s, 6));
|
||||
setArg<9>(fmt::string_view(nanosecond.s, 3));
|
||||
setArg<10>(fmt::string_view(second.s, 2));
|
||||
setArg<11>(fmt::string_view(minute.s, 2));
|
||||
setArg<12>(fmt::string_view(hour.s, 2));
|
||||
setArg<13>(fmt::string_view(logLevel.s, 3));
|
||||
setArg<14>(fmt::string_view());
|
||||
setArg<15>(fmt::string_view());
|
||||
setArg<16>(fmt::string_view(year.s, 10)); // Ymd
|
||||
setArg<17>(fmt::string_view(hour.s, 8)); // HMS
|
||||
setArg<18>(fmt::string_view(hour.s, 12)); // HMSe
|
||||
setArg<19>(fmt::string_view(hour.s, 15)); // HMSf
|
||||
setArg<20>(fmt::string_view(hour.s, 18)); // HMSF
|
||||
setArg<21>(fmt::string_view(year.s, 19)); // YmdHMS
|
||||
setArg<22>(fmt::string_view(year.s, 23)); // YmdHMSe
|
||||
setArg<23>(fmt::string_view(year.s, 26)); // YmdHMSf
|
||||
setArg<24>(fmt::string_view(year.s, 29)); // YmdHMSF
|
||||
}
|
||||
|
||||
class ThreadBufferDestroyer
|
||||
{
|
||||
public:
|
||||
explicit ThreadBufferDestroyer() {}
|
||||
|
||||
void threadBufferCreated() {}
|
||||
|
||||
~ThreadBufferDestroyer() {
|
||||
if (fmtlog::threadBuffer != nullptr) {
|
||||
fmtlog::threadBuffer->shouldDeallocate = true;
|
||||
fmtlog::threadBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct StaticLogInfo
|
||||
{
|
||||
// Constructor
|
||||
constexpr StaticLogInfo(fmtlog::FormatToFn fn, const char* loc, fmtlog::LogLevel level, fmt::string_view fmtString)
|
||||
: formatToFn(fn)
|
||||
, formatString(fmtString)
|
||||
, location(loc)
|
||||
, logLevel(level)
|
||||
, argIdx(-1) {}
|
||||
|
||||
void processLocation() {
|
||||
size_t size = strlen(location);
|
||||
const char* p = location + size;
|
||||
if (size > 255) {
|
||||
location = p - 255;
|
||||
}
|
||||
endPos = p - location;
|
||||
const char* base = location;
|
||||
while (p > location) {
|
||||
char c = *--p;
|
||||
if (c == '/' || c == '\\') {
|
||||
base = p + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
basePos = base - location;
|
||||
}
|
||||
|
||||
inline fmt::string_view getBase() { return fmt::string_view(location + basePos, endPos - basePos); }
|
||||
|
||||
inline fmt::string_view getLocation() { return fmt::string_view(location, endPos); }
|
||||
|
||||
fmtlog::FormatToFn formatToFn;
|
||||
fmt::string_view formatString;
|
||||
const char* location;
|
||||
uint8_t basePos;
|
||||
uint8_t endPos;
|
||||
fmtlog::LogLevel logLevel;
|
||||
int argIdx;
|
||||
};
|
||||
|
||||
static thread_local ThreadBufferDestroyer sbc;
|
||||
int64_t midnightNs;
|
||||
fmt::string_view headerPattern;
|
||||
bool shouldDeallocateHeader = false;
|
||||
FILE* outputFp = nullptr;
|
||||
bool manageFp = false;
|
||||
size_t fpos = 0; // file position of membuf, used only when manageFp == true
|
||||
int64_t flushDelay;
|
||||
int64_t nextFlushTime = (std::numeric_limits<int64_t>::max)();
|
||||
uint32_t flushBufSize = 8 * 1024;
|
||||
fmtlog::LogLevel flushLogLevel = fmtlog::OFF;
|
||||
std::mutex bufferMutex;
|
||||
std::vector<fmtlog::ThreadBuffer*> threadBuffers;
|
||||
struct HeapNode
|
||||
{
|
||||
HeapNode(fmtlog::ThreadBuffer* buffer)
|
||||
: tb(buffer) {}
|
||||
|
||||
fmtlog::ThreadBuffer* tb;
|
||||
const fmtlog::SPSCVarQueueOPT::MsgHeader* header = nullptr;
|
||||
};
|
||||
std::vector<HeapNode> bgThreadBuffers;
|
||||
std::mutex logInfoMutex;
|
||||
std::vector<StaticLogInfo> logInfos;
|
||||
std::vector<StaticLogInfo> bgLogInfos;
|
||||
|
||||
fmtlog::LogCBFn logCB = nullptr;
|
||||
fmtlog::LogLevel minCBLogLevel;
|
||||
fmtlog::LogQFullCBFn logQFullCB = fmtlogEmptyFun;
|
||||
void* logQFullCBArg = nullptr;
|
||||
|
||||
fmtlog::MemoryBuffer membuf;
|
||||
|
||||
const static int parttenArgSize = 25;
|
||||
uint32_t reorderIdx[parttenArgSize];
|
||||
Str<3> weekdayName;
|
||||
Str<3> monthName;
|
||||
Str<4> year;
|
||||
char dash1 = '-';
|
||||
Str<2> month;
|
||||
char dash2 = '-';
|
||||
Str<2> day;
|
||||
char space = ' ';
|
||||
Str<2> hour;
|
||||
char colon1 = ':';
|
||||
Str<2> minute;
|
||||
char colon2 = ':';
|
||||
Str<2> second;
|
||||
char dot1 = '.';
|
||||
Str<9> nanosecond;
|
||||
Str<3> logLevel;
|
||||
std::vector<fmt::basic_format_arg<fmtlog::Context>> args;
|
||||
|
||||
volatile bool threadRunning = false;
|
||||
std::thread thr;
|
||||
|
||||
void resetDate() {
|
||||
time_t rawtime = fmtlogWrapper<>::impl.tscns.rdns() / 1000000000;
|
||||
struct tm* timeinfo = localtime(&rawtime);
|
||||
timeinfo->tm_sec = timeinfo->tm_min = timeinfo->tm_hour = 0;
|
||||
midnightNs = mktime(timeinfo) * 1000000000;
|
||||
year.fromi(1900 + timeinfo->tm_year);
|
||||
month.fromi(1 + timeinfo->tm_mon);
|
||||
day.fromi(timeinfo->tm_mday);
|
||||
const char* weekdays[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||
weekdayName = weekdays[timeinfo->tm_wday];
|
||||
const char* monthNames[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
monthName = monthNames[timeinfo->tm_mon];
|
||||
}
|
||||
|
||||
void preallocate() {
|
||||
if (fmtlog::threadBuffer) return;
|
||||
fmtlog::threadBuffer = new fmtlog::ThreadBuffer();
|
||||
#ifdef _WIN32
|
||||
uint32_t tid = static_cast<uint32_t>(::GetCurrentThreadId());
|
||||
#else
|
||||
uint32_t tid = static_cast<uint32_t>(::syscall(SYS_gettid));
|
||||
#endif
|
||||
fmtlog::threadBuffer->nameSize =
|
||||
fmt::format_to_n(fmtlog::threadBuffer->name, sizeof(fmtlog::threadBuffer->name), "{}", tid).size;
|
||||
sbc.threadBufferCreated();
|
||||
|
||||
std::unique_lock<std::mutex> guard(bufferMutex);
|
||||
threadBuffers.push_back(fmtlog::threadBuffer);
|
||||
}
|
||||
|
||||
template<size_t I, typename T>
|
||||
inline void setArg(const T& arg) {
|
||||
args[reorderIdx[I]] = fmt::detail::make_arg<fmtlog::Context>(arg);
|
||||
}
|
||||
|
||||
template<size_t I, typename T>
|
||||
inline void setArgVal(const T& arg) {
|
||||
fmt::detail::value<fmtlog::Context>& value_ = *(fmt::detail::value<fmtlog::Context>*)&args[reorderIdx[I]];
|
||||
value_ = fmt::detail::arg_mapper<fmtlog::Context>().map(arg);
|
||||
}
|
||||
|
||||
void flushLogFile() {
|
||||
if (outputFp) {
|
||||
fwrite(membuf.data(), 1, membuf.size(), outputFp);
|
||||
if (!manageFp) fflush(outputFp);
|
||||
else
|
||||
fpos += membuf.size();
|
||||
}
|
||||
membuf.clear();
|
||||
nextFlushTime = (std::numeric_limits<int64_t>::max)();
|
||||
}
|
||||
|
||||
void closeLogFile() {
|
||||
if (membuf.size()) flushLogFile();
|
||||
if (manageFp) fclose(outputFp);
|
||||
outputFp = nullptr;
|
||||
manageFp = false;
|
||||
}
|
||||
|
||||
void startPollingThread(int64_t pollInterval) {
|
||||
stopPollingThread();
|
||||
threadRunning = true;
|
||||
thr = std::thread([pollInterval, this]() {
|
||||
while (threadRunning) {
|
||||
int64_t before = fmtlogWrapper<>::impl.tscns.rdns();
|
||||
poll(false);
|
||||
int64_t delay = fmtlogWrapper<>::impl.tscns.rdns() - before;
|
||||
if (delay < pollInterval) {
|
||||
std::this_thread::sleep_for(std::chrono::nanoseconds(pollInterval - delay));
|
||||
}
|
||||
}
|
||||
poll(true);
|
||||
});
|
||||
}
|
||||
|
||||
void stopPollingThread() {
|
||||
if (!threadRunning) return;
|
||||
threadRunning = false;
|
||||
if (thr.joinable()) thr.join();
|
||||
}
|
||||
|
||||
void handleLog(fmt::string_view threadName, const fmtlog::SPSCVarQueueOPT::MsgHeader* header) {
|
||||
setArgVal<6>(threadName);
|
||||
StaticLogInfo& info = bgLogInfos[header->logId];
|
||||
const char* data = (const char*)(header + 1);
|
||||
const char* end = (const char*)header + header->size;
|
||||
int64_t tsc = *(int64_t*)data;
|
||||
data += 8;
|
||||
if (!info.formatToFn) { // log once
|
||||
info.location = *(const char**)data;
|
||||
data += 8;
|
||||
info.processLocation();
|
||||
}
|
||||
int64_t ts = fmtlogWrapper<>::impl.tscns.tsc2ns(tsc);
|
||||
// the date could go back when polling different threads
|
||||
uint64_t t = (ts > midnightNs) ? (ts - midnightNs) : 0;
|
||||
nanosecond.fromi(t % 1000000000);
|
||||
t /= 1000000000;
|
||||
second.fromi(t % 60);
|
||||
t /= 60;
|
||||
minute.fromi(t % 60);
|
||||
t /= 60;
|
||||
uint32_t h = t; // hour
|
||||
if (h > 23) {
|
||||
h %= 24;
|
||||
resetDate();
|
||||
}
|
||||
hour.fromi(h);
|
||||
setArgVal<14>(info.getBase());
|
||||
setArgVal<15>(info.getLocation());
|
||||
logLevel = (const char*)"DBG INF WRN ERR OFF" + (info.logLevel << 2);
|
||||
|
||||
size_t headerPos = membuf.size();
|
||||
fmtlog::vformat_to(membuf, headerPattern, fmt::basic_format_args(args.data(), parttenArgSize));
|
||||
size_t bodyPos = membuf.size();
|
||||
|
||||
if (info.formatToFn) {
|
||||
info.formatToFn(info.formatString, data, membuf, info.argIdx, args);
|
||||
}
|
||||
else { // log once
|
||||
membuf.append(fmt::string_view(data, end - data));
|
||||
}
|
||||
|
||||
if (logCB && info.logLevel >= minCBLogLevel) {
|
||||
logCB(ts, info.logLevel, info.getLocation(), info.basePos, threadName,
|
||||
fmt::string_view(membuf.data() + headerPos, membuf.size() - headerPos), bodyPos - headerPos,
|
||||
fpos + headerPos);
|
||||
}
|
||||
membuf.push_back('\n');
|
||||
if (membuf.size() >= flushBufSize || info.logLevel >= flushLogLevel) {
|
||||
flushLogFile();
|
||||
}
|
||||
}
|
||||
|
||||
void adjustHeap(size_t i) {
|
||||
while (true) {
|
||||
size_t min_i = i;
|
||||
for (size_t ch = i * 2 + 1, end = std::min(ch + 2, bgThreadBuffers.size()); ch < end; ch++) {
|
||||
auto h_ch = bgThreadBuffers[ch].header;
|
||||
auto h_min = bgThreadBuffers[min_i].header;
|
||||
if (h_ch && (!h_min || *(int64_t*)(h_ch + 1) < *(int64_t*)(h_min + 1))) min_i = ch;
|
||||
}
|
||||
if (min_i == i) break;
|
||||
std::swap(bgThreadBuffers[i], bgThreadBuffers[min_i]);
|
||||
i = min_i;
|
||||
}
|
||||
}
|
||||
|
||||
void poll(bool forceFlush) {
|
||||
fmtlogWrapper<>::impl.tscns.calibrate();
|
||||
int64_t tsc = fmtlogWrapper<>::impl.tscns.rdtsc();
|
||||
if (logInfos.size()) {
|
||||
std::unique_lock<std::mutex> lock(logInfoMutex);
|
||||
for (auto& info : logInfos) {
|
||||
info.processLocation();
|
||||
}
|
||||
bgLogInfos.insert(bgLogInfos.end(), logInfos.begin(), logInfos.end());
|
||||
logInfos.clear();
|
||||
}
|
||||
if (threadBuffers.size()) {
|
||||
std::unique_lock<std::mutex> lock(bufferMutex);
|
||||
for (auto tb : threadBuffers) {
|
||||
bgThreadBuffers.emplace_back(tb);
|
||||
}
|
||||
threadBuffers.clear();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < bgThreadBuffers.size(); i++) {
|
||||
auto& node = bgThreadBuffers[i];
|
||||
if (node.header) continue;
|
||||
node.header = node.tb->varq.front();
|
||||
if (!node.header && node.tb->shouldDeallocate) {
|
||||
delete node.tb;
|
||||
node = bgThreadBuffers.back();
|
||||
bgThreadBuffers.pop_back();
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
if (bgThreadBuffers.empty()) return;
|
||||
|
||||
// build heap
|
||||
for (int i = bgThreadBuffers.size() / 2; i >= 0; i--) {
|
||||
adjustHeap(i);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
auto h = bgThreadBuffers[0].header;
|
||||
if (!h || h->logId >= bgLogInfos.size() || *(int64_t*)(h + 1) >= tsc) break;
|
||||
auto tb = bgThreadBuffers[0].tb;
|
||||
handleLog(fmt::string_view(tb->name, tb->nameSize), h);
|
||||
tb->varq.pop();
|
||||
bgThreadBuffers[0].header = tb->varq.front();
|
||||
adjustHeap(0);
|
||||
}
|
||||
|
||||
if (membuf.size() == 0) return;
|
||||
if (!manageFp || forceFlush) {
|
||||
flushLogFile();
|
||||
return;
|
||||
}
|
||||
int64_t now = fmtlogWrapper<>::impl.tscns.tsc2ns(tsc);
|
||||
if (now > nextFlushTime) {
|
||||
flushLogFile();
|
||||
}
|
||||
else if (nextFlushTime == (std::numeric_limits<int64_t>::max)()) {
|
||||
nextFlushTime = now + flushDelay;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<int _>
|
||||
thread_local typename fmtlogDetailT<_>::ThreadBufferDestroyer fmtlogDetailT<_>::sbc;
|
||||
|
||||
template<int __ = 0>
|
||||
struct fmtlogDetailWrapper
|
||||
{ static fmtlogDetailT<> impl; };
|
||||
|
||||
template<int _>
|
||||
fmtlogDetailT<> fmtlogDetailWrapper<_>::impl;
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::registerLogInfo(uint32_t& logId, FormatToFn fn, const char* location,
|
||||
LogLevel level, fmt::string_view fmtString) noexcept {
|
||||
auto& d = fmtlogDetailWrapper<>::impl;
|
||||
std::lock_guard<std::mutex> lock(d.logInfoMutex);
|
||||
if (logId) return;
|
||||
logId = d.logInfos.size() + d.bgLogInfos.size();
|
||||
d.logInfos.emplace_back(fn, location, level, fmtString);
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::vformat_to(fmtlog::MemoryBuffer& out, fmt::string_view fmt,
|
||||
fmt::format_args args) {
|
||||
fmt::detail::vformat_to(out, fmt, args);
|
||||
}
|
||||
|
||||
template<int _>
|
||||
size_t fmtlogT<_>::formatted_size(fmt::string_view fmt, fmt::format_args args) {
|
||||
auto buf = fmt::detail::counting_buffer<>();
|
||||
fmt::detail::vformat_to(buf, fmt, args);
|
||||
return buf.count();
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::vformat_to(char* out, fmt::string_view fmt, fmt::format_args args) {
|
||||
fmt::vformat_to(out, fmt, args);
|
||||
}
|
||||
|
||||
template<int _>
|
||||
typename fmtlogT<_>::SPSCVarQueueOPT::MsgHeader* fmtlogT<_>::allocMsg(uint32_t size,
|
||||
bool q_full_cb) noexcept {
|
||||
auto& d = fmtlogDetailWrapper<>::impl;
|
||||
if (threadBuffer == nullptr) preallocate();
|
||||
auto ret = threadBuffer->varq.alloc(size);
|
||||
if ((ret == nullptr) & q_full_cb) d.logQFullCB(d.logQFullCBArg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
typename fmtlogT<_>::SPSCVarQueueOPT::MsgHeader*
|
||||
fmtlogT<_>::SPSCVarQueueOPT::allocMsg(uint32_t size) noexcept {
|
||||
return alloc(size);
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::preallocate() noexcept {
|
||||
fmtlogDetailWrapper<>::impl.preallocate();
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::setLogFile(const char* filename, bool truncate) {
|
||||
auto& d = fmtlogDetailWrapper<>::impl;
|
||||
FILE* newFp = fopen(filename, truncate ? "w" : "a");
|
||||
if (!newFp) {
|
||||
std::string err = fmt::format("Unable to open file: {}: {}", filename, strerror(errno));
|
||||
fmt::detail::throw_format_error(err.c_str());
|
||||
}
|
||||
setbuf(newFp, nullptr);
|
||||
d.fpos = ftell(newFp);
|
||||
|
||||
closeLogFile();
|
||||
d.outputFp = newFp;
|
||||
d.manageFp = true;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::setLogFile(FILE* fp, bool manageFp) {
|
||||
auto& d = fmtlogDetailWrapper<>::impl;
|
||||
closeLogFile();
|
||||
if (manageFp) {
|
||||
setbuf(fp, nullptr);
|
||||
d.fpos = ftell(fp);
|
||||
}
|
||||
else
|
||||
d.fpos = 0;
|
||||
d.outputFp = fp;
|
||||
d.manageFp = manageFp;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::setFlushDelay(int64_t ns) noexcept {
|
||||
fmtlogDetailWrapper<>::impl.flushDelay = ns;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::flushOn(LogLevel flushLogLevel) noexcept {
|
||||
fmtlogDetailWrapper<>::impl.flushLogLevel = flushLogLevel;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::setFlushBufSize(uint32_t bytes) noexcept {
|
||||
fmtlogDetailWrapper<>::impl.flushBufSize = bytes;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::closeLogFile() noexcept {
|
||||
fmtlogDetailWrapper<>::impl.closeLogFile();
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::poll(bool forceFlush) {
|
||||
fmtlogDetailWrapper<>::impl.poll(forceFlush);
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::setThreadName(const char* name) noexcept {
|
||||
preallocate();
|
||||
threadBuffer->nameSize = fmt::format_to_n(threadBuffer->name, sizeof(fmtlog::threadBuffer->name), "{}", name).size;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::setLogCB(LogCBFn cb, LogLevel minCBLogLevel_) noexcept {
|
||||
auto& d = fmtlogDetailWrapper<>::impl;
|
||||
d.logCB = cb;
|
||||
d.minCBLogLevel = minCBLogLevel_;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::setLogQFullCB(LogQFullCBFn cb, void* userData) noexcept {
|
||||
auto& d = fmtlogDetailWrapper<>::impl;
|
||||
d.logQFullCB = cb;
|
||||
d.logQFullCBArg = userData;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::setHeaderPattern(const char* pattern) {
|
||||
fmtlogDetailWrapper<>::impl.setHeaderPattern(pattern);
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::startPollingThread(int64_t pollInterval) noexcept {
|
||||
fmtlogDetailWrapper<>::impl.startPollingThread(pollInterval);
|
||||
}
|
||||
|
||||
template<int _>
|
||||
void fmtlogT<_>::stopPollingThread() noexcept {
|
||||
fmtlogDetailWrapper<>::impl.stopPollingThread();
|
||||
}
|
||||
|
||||
template class fmtlogT<0>;
|
||||
|
|
@ -0,0 +1 @@
|
|||
#include "fmtlog-inl.h"
|
|
@ -0,0 +1,826 @@
|
|||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Meng Rao <raomeng1@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
//#define FMT_HEADER_ONLY
|
||||
#include "fmt/format.h"
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define FAST_THREAD_LOCAL thread_local
|
||||
#else
|
||||
#define FAST_THREAD_LOCAL __thread
|
||||
#endif
|
||||
|
||||
// define FMTLOG_BLOCK=1 if log statment should be blocked when queue is full, instead of discarding the msg
|
||||
#ifndef FMTLOG_BLOCK
|
||||
#define FMTLOG_BLOCK 0
|
||||
#endif
|
||||
|
||||
#define FMTLOG_LEVEL_DBG 0
|
||||
#define FMTLOG_LEVEL_INF 1
|
||||
#define FMTLOG_LEVEL_WRN 2
|
||||
#define FMTLOG_LEVEL_ERR 3
|
||||
#define FMTLOG_LEVEL_OFF 4
|
||||
|
||||
// define FMTLOG_ACTIVE_LEVEL to turn off low log level in compile time
|
||||
#ifndef FMTLOG_ACTIVE_LEVEL
|
||||
#define FMTLOG_ACTIVE_LEVEL FMTLOG_LEVEL_DBG
|
||||
#endif
|
||||
|
||||
#ifndef FMTLOG_QUEUE_SIZE
|
||||
#define FMTLOG_QUEUE_SIZE (1 << 20)
|
||||
#endif
|
||||
|
||||
namespace fmtlogdetail {
|
||||
template<typename Arg>
|
||||
struct UnrefPtr : std::false_type
|
||||
{ using type = Arg; };
|
||||
|
||||
template<>
|
||||
struct UnrefPtr<char*> : std::false_type
|
||||
{ using type = char*; };
|
||||
|
||||
template<>
|
||||
struct UnrefPtr<void*> : std::false_type
|
||||
{ using type = void*; };
|
||||
|
||||
template<typename Arg>
|
||||
struct UnrefPtr<std::shared_ptr<Arg>> : std::true_type
|
||||
{ using type = Arg; };
|
||||
|
||||
template<typename Arg, typename D>
|
||||
struct UnrefPtr<std::unique_ptr<Arg, D>> : std::true_type
|
||||
{ using type = Arg; };
|
||||
|
||||
template<typename Arg>
|
||||
struct UnrefPtr<Arg*> : std::true_type
|
||||
{ using type = Arg; };
|
||||
|
||||
}; // namespace fmtlogdetail
|
||||
|
||||
template<int __ = 0>
|
||||
class fmtlogT
|
||||
{
|
||||
public:
|
||||
enum LogLevel : uint8_t
|
||||
{
|
||||
DBG = 0,
|
||||
INF,
|
||||
WRN,
|
||||
ERR,
|
||||
OFF
|
||||
};
|
||||
|
||||
// Preallocate thread queue for current thread
|
||||
static void preallocate() noexcept;
|
||||
|
||||
// Set the file for logging
|
||||
static void setLogFile(const char* filename, bool truncate = false);
|
||||
|
||||
// Set an existing FILE* for logging, if manageFp is false fmtlog will not buffer log internally
|
||||
// and will not close the FILE*
|
||||
static void setLogFile(FILE* fp, bool manageFp = false);
|
||||
|
||||
// Collect log msgs from all threads and write to log file
|
||||
// If forceFlush = true, internal file buffer is flushed
|
||||
// User need to call poll() repeatedly if startPollingThread is not used
|
||||
static void poll(bool forceFlush = false);
|
||||
|
||||
// Set flush delay in nanosecond
|
||||
// If there's msg older than ns in the buffer, flush will be triggered
|
||||
static void setFlushDelay(int64_t ns) noexcept;
|
||||
|
||||
// If current msg has level >= flushLogLevel, flush will be triggered
|
||||
static void flushOn(LogLevel flushLogLevel) noexcept;
|
||||
|
||||
// If file buffer has more than specified bytes, flush will be triggered
|
||||
static void setFlushBufSize(uint32_t bytes) noexcept;
|
||||
|
||||
// callback signature user can register
|
||||
// ns: nanosecond timestamp
|
||||
// level: logLevel
|
||||
// location: full file path with line num, e.g: /home/raomeng/fmtlog/fmtlog.h:45
|
||||
// basePos: file base index in the location
|
||||
// threadName: thread id or the name user set with setThreadName
|
||||
// msg: full log msg with header
|
||||
// bodyPos: log body index in the msg
|
||||
// logFilePos: log file position of this msg
|
||||
typedef void (*LogCBFn)(int64_t ns, LogLevel level, fmt::string_view location, size_t basePos,
|
||||
fmt::string_view threadName, fmt::string_view msg, size_t bodyPos,
|
||||
size_t logFilePos);
|
||||
|
||||
// Set a callback function for all log msgs with a mininum log level
|
||||
static void setLogCB(LogCBFn cb, LogLevel minCBLogLevel) noexcept;
|
||||
|
||||
typedef void (*LogQFullCBFn)(void* userData);
|
||||
static void setLogQFullCB(LogQFullCBFn cb, void* userData) noexcept;
|
||||
|
||||
// Close the log file and subsequent msgs will not be written into the file,
|
||||
// but callback function can still be used
|
||||
static void closeLogFile() noexcept;
|
||||
|
||||
// Set log header pattern with fmt named arguments
|
||||
static void setHeaderPattern(const char* pattern);
|
||||
|
||||
// Set a name for current thread, it'll be shown in {t} part in header pattern
|
||||
static void setThreadName(const char* name) noexcept;
|
||||
|
||||
// Set current log level, lower level log msgs will be discarded
|
||||
static inline void setLogLevel(LogLevel logLevel) noexcept;
|
||||
|
||||
// Get current log level
|
||||
static inline LogLevel getLogLevel() noexcept;
|
||||
|
||||
// return true if passed log level is not lower than current log level
|
||||
static inline bool checkLogLevel(LogLevel logLevel) noexcept;
|
||||
|
||||
// Run a polling thread in the background with a polling interval in ns
|
||||
// Note that user must not call poll() himself when the thread is running
|
||||
static void startPollingThread(int64_t pollInterval = 1000000000) noexcept;
|
||||
|
||||
// Stop the polling thread
|
||||
static void stopPollingThread() noexcept;
|
||||
|
||||
// https://github.com/MengRao/SPSC_Queue
|
||||
class SPSCVarQueueOPT
|
||||
{
|
||||
public:
|
||||
struct MsgHeader
|
||||
{
|
||||
inline void push(uint32_t sz) { *(volatile uint32_t*)&size = sz + sizeof(MsgHeader); }
|
||||
|
||||
uint32_t size;
|
||||
uint32_t logId;
|
||||
};
|
||||
static constexpr uint32_t BLK_CNT = FMTLOG_QUEUE_SIZE / sizeof(MsgHeader);
|
||||
|
||||
MsgHeader* allocMsg(uint32_t size) noexcept;
|
||||
|
||||
MsgHeader* alloc(uint32_t size) {
|
||||
size += sizeof(MsgHeader);
|
||||
uint32_t blk_sz = (size + sizeof(MsgHeader) - 1) / sizeof(MsgHeader);
|
||||
if (blk_sz >= free_write_cnt) {
|
||||
uint32_t read_idx_cache = *(volatile uint32_t*)&read_idx;
|
||||
if (read_idx_cache <= write_idx) {
|
||||
free_write_cnt = BLK_CNT - write_idx;
|
||||
if (blk_sz >= free_write_cnt && read_idx_cache != 0) { // wrap around
|
||||
blk[0].size = 0;
|
||||
blk[write_idx].size = 1;
|
||||
write_idx = 0;
|
||||
free_write_cnt = read_idx_cache;
|
||||
}
|
||||
}
|
||||
else {
|
||||
free_write_cnt = read_idx_cache - write_idx;
|
||||
}
|
||||
if (free_write_cnt <= blk_sz) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
MsgHeader* ret = &blk[write_idx];
|
||||
write_idx += blk_sz;
|
||||
free_write_cnt -= blk_sz;
|
||||
blk[write_idx].size = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline const MsgHeader* front() {
|
||||
uint32_t size = blk[read_idx].size;
|
||||
if (size == 1) { // wrap around
|
||||
read_idx = 0;
|
||||
size = blk[0].size;
|
||||
}
|
||||
if (size == 0) return nullptr;
|
||||
return &blk[read_idx];
|
||||
}
|
||||
|
||||
inline void pop() {
|
||||
uint32_t blk_sz = (blk[read_idx].size + sizeof(MsgHeader) - 1) / sizeof(MsgHeader);
|
||||
*(volatile uint32_t*)&read_idx = read_idx + blk_sz;
|
||||
}
|
||||
|
||||
private:
|
||||
alignas(64) MsgHeader blk[BLK_CNT] = {};
|
||||
uint32_t write_idx = 0;
|
||||
uint32_t free_write_cnt = BLK_CNT;
|
||||
|
||||
alignas(128) uint32_t read_idx = 0;
|
||||
};
|
||||
|
||||
struct ThreadBuffer
|
||||
{
|
||||
SPSCVarQueueOPT varq;
|
||||
bool shouldDeallocate = false;
|
||||
char name[32];
|
||||
size_t nameSize;
|
||||
};
|
||||
|
||||
// https://github.com/MengRao/tscns
|
||||
class TSCNS
|
||||
{
|
||||
public:
|
||||
static const int64_t NsPerSec = 1000000000;
|
||||
|
||||
void init(int64_t init_calibrate_ns = 20000000, int64_t calibrate_interval_ns = 3 * NsPerSec) {
|
||||
calibate_interval_ns_ = calibrate_interval_ns;
|
||||
int64_t base_tsc, base_ns;
|
||||
syncTime(base_tsc, base_ns);
|
||||
int64_t expire_ns = base_ns + init_calibrate_ns;
|
||||
while (rdsysns() < expire_ns) std::this_thread::yield();
|
||||
int64_t delayed_tsc, delayed_ns;
|
||||
syncTime(delayed_tsc, delayed_ns);
|
||||
double init_ns_per_tsc = (double)(delayed_ns - base_ns) / (delayed_tsc - base_tsc);
|
||||
saveParam(base_tsc, base_ns, base_ns, init_ns_per_tsc);
|
||||
}
|
||||
|
||||
void calibrate() {
|
||||
if (rdtsc() < next_calibrate_tsc_) return;
|
||||
int64_t tsc, ns;
|
||||
syncTime(tsc, ns);
|
||||
int64_t calulated_ns = tsc2ns(tsc);
|
||||
int64_t ns_err = calulated_ns - ns;
|
||||
int64_t expected_err_at_next_calibration =
|
||||
ns_err + (ns_err - base_ns_err_) * calibate_interval_ns_ / (ns - base_ns_ + base_ns_err_);
|
||||
double new_ns_per_tsc =
|
||||
ns_per_tsc_ * (1.0 - (double)expected_err_at_next_calibration / calibate_interval_ns_);
|
||||
saveParam(tsc, calulated_ns, ns, new_ns_per_tsc);
|
||||
}
|
||||
|
||||
static inline int64_t rdtsc() {
|
||||
#ifdef _MSC_VER
|
||||
return __rdtsc();
|
||||
#elif defined(__i386__) || defined(__x86_64__) || defined(__amd64__)
|
||||
return __builtin_ia32_rdtsc();
|
||||
#else
|
||||
return rdsysns();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int64_t tsc2ns(int64_t tsc) const {
|
||||
while (true) {
|
||||
uint32_t before_seq = param_seq_.load(std::memory_order_acquire) & ~1;
|
||||
std::atomic_signal_fence(std::memory_order_acq_rel);
|
||||
int64_t ns = base_ns_ + (int64_t)((tsc - base_tsc_) * ns_per_tsc_);
|
||||
std::atomic_signal_fence(std::memory_order_acq_rel);
|
||||
uint32_t after_seq = param_seq_.load(std::memory_order_acquire);
|
||||
if (before_seq == after_seq) return ns;
|
||||
}
|
||||
}
|
||||
|
||||
inline int64_t rdns() const { return tsc2ns(rdtsc()); }
|
||||
|
||||
static inline int64_t rdsysns() {
|
||||
using namespace std::chrono;
|
||||
return duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
double getTscGhz() const { return 1.0 / ns_per_tsc_; }
|
||||
|
||||
// Linux kernel sync time by finding the first trial with tsc diff < 50000
|
||||
// We try several times and return the one with the mininum tsc diff.
|
||||
// Note that MSVC has a 100ns resolution clock, so we need to combine those ns with the same
|
||||
// value, and drop the first and the last value as they may not scan a full 100ns range
|
||||
static void syncTime(int64_t& tsc_out, int64_t& ns_out) {
|
||||
#ifdef _MSC_VER
|
||||
const int N = 15;
|
||||
#else
|
||||
const int N = 3;
|
||||
#endif
|
||||
int64_t tsc[N + 1];
|
||||
int64_t ns[N + 1];
|
||||
|
||||
tsc[0] = rdtsc();
|
||||
for (int i = 1; i <= N; i++) {
|
||||
ns[i] = rdsysns();
|
||||
tsc[i] = rdtsc();
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
int j = 1;
|
||||
for (int i = 2; i <= N; i++) {
|
||||
if (ns[i] == ns[i - 1]) continue;
|
||||
tsc[j - 1] = tsc[i - 1];
|
||||
ns[j++] = ns[i];
|
||||
}
|
||||
j--;
|
||||
#else
|
||||
int j = N + 1;
|
||||
#endif
|
||||
|
||||
int best = 1;
|
||||
for (int i = 2; i < j; i++) {
|
||||
if (tsc[i] - tsc[i - 1] < tsc[best] - tsc[best - 1]) best = i;
|
||||
}
|
||||
tsc_out = (tsc[best] + tsc[best - 1]) >> 1;
|
||||
ns_out = ns[best];
|
||||
}
|
||||
|
||||
void saveParam(int64_t base_tsc, int64_t base_ns, int64_t sys_ns, double new_ns_per_tsc) {
|
||||
base_ns_err_ = base_ns - sys_ns;
|
||||
next_calibrate_tsc_ = base_tsc + (int64_t)((calibate_interval_ns_ - 1000) / new_ns_per_tsc);
|
||||
uint32_t seq = param_seq_.load(std::memory_order_relaxed);
|
||||
param_seq_.store(++seq, std::memory_order_release);
|
||||
std::atomic_signal_fence(std::memory_order_acq_rel);
|
||||
base_tsc_ = base_tsc;
|
||||
base_ns_ = base_ns;
|
||||
ns_per_tsc_ = new_ns_per_tsc;
|
||||
std::atomic_signal_fence(std::memory_order_acq_rel);
|
||||
param_seq_.store(++seq, std::memory_order_release);
|
||||
}
|
||||
|
||||
alignas(64) std::atomic<uint32_t> param_seq_ = 0;
|
||||
double ns_per_tsc_;
|
||||
int64_t base_tsc_;
|
||||
int64_t base_ns_;
|
||||
int64_t calibate_interval_ns_;
|
||||
int64_t base_ns_err_;
|
||||
int64_t next_calibrate_tsc_;
|
||||
};
|
||||
|
||||
void init() {
|
||||
tscns.init();
|
||||
currentLogLevel = INF;
|
||||
}
|
||||
|
||||
using Context = fmt::format_context;
|
||||
using MemoryBuffer = fmt::basic_memory_buffer<char, 10000>;
|
||||
typedef const char* (*FormatToFn)(fmt::string_view format, const char* data, MemoryBuffer& out,
|
||||
int& argIdx, std::vector<fmt::basic_format_arg<Context>>& args);
|
||||
|
||||
static void registerLogInfo(uint32_t& logId, FormatToFn fn, const char* location, LogLevel level,
|
||||
fmt::string_view fmtString) noexcept;
|
||||
|
||||
static void vformat_to(MemoryBuffer& out, fmt::string_view fmt, fmt::format_args args);
|
||||
|
||||
static size_t formatted_size(fmt::string_view fmt, fmt::format_args args);
|
||||
|
||||
static void vformat_to(char* out, fmt::string_view fmt, fmt::format_args args);
|
||||
|
||||
static typename SPSCVarQueueOPT::MsgHeader* allocMsg(uint32_t size, bool logQFullCB) noexcept;
|
||||
|
||||
TSCNS tscns;
|
||||
|
||||
volatile LogLevel currentLogLevel;
|
||||
static FAST_THREAD_LOCAL ThreadBuffer* threadBuffer;
|
||||
|
||||
template<typename Arg>
|
||||
static inline constexpr bool isNamedArg() {
|
||||
return fmt::detail::is_named_arg<fmt::remove_cvref_t<Arg>>::value;
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
struct unNamedType
|
||||
{ using type = Arg; };
|
||||
|
||||
template<typename Arg>
|
||||
struct unNamedType<fmt::detail::named_arg<char, Arg>>
|
||||
{ using type = Arg; };
|
||||
|
||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
template<typename Arg, size_t N, fmt::detail_exported::fixed_string<char, N> Str>
|
||||
struct unNamedType<fmt::detail::statically_named_arg<Arg, char, N, Str>>
|
||||
{ using type = Arg; };
|
||||
#endif
|
||||
|
||||
template<typename Arg>
|
||||
static inline constexpr bool isCstring() {
|
||||
return fmt::detail::mapped_type_constant<Arg, Context>::value ==
|
||||
fmt::detail::type::cstring_type;
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
static inline constexpr bool isString() {
|
||||
return fmt::detail::mapped_type_constant<Arg, Context>::value == fmt::detail::type::string_type;
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
static inline constexpr bool needCallDtor() {
|
||||
using ArgType = fmt::remove_cvref_t<Arg>;
|
||||
if constexpr (isNamedArg<Arg>()) {
|
||||
return needCallDtor<typename unNamedType<ArgType>::type>();
|
||||
}
|
||||
if constexpr (isString<Arg>()) return false;
|
||||
return !std::is_trivially_destructible<ArgType>::value;
|
||||
}
|
||||
|
||||
template<size_t CstringIdx>
|
||||
static inline constexpr size_t getArgSizes(size_t* cstringSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<size_t CstringIdx, typename Arg, typename... Args>
|
||||
static inline constexpr size_t getArgSizes(size_t* cstringSize, const Arg& arg,
|
||||
const Args&... args) {
|
||||
if constexpr (isNamedArg<Arg>()) {
|
||||
return getArgSizes<CstringIdx>(cstringSize, arg.value, args...);
|
||||
}
|
||||
else if constexpr (isCstring<Arg>()) {
|
||||
size_t len = strlen(arg) + 1;
|
||||
cstringSize[CstringIdx] = len;
|
||||
return len + getArgSizes<CstringIdx + 1>(cstringSize, args...);
|
||||
}
|
||||
else if constexpr (isString<Arg>()) {
|
||||
size_t len = arg.size() + 1;
|
||||
return len + getArgSizes<CstringIdx>(cstringSize, args...);
|
||||
}
|
||||
else {
|
||||
return sizeof(Arg) + getArgSizes<CstringIdx>(cstringSize, args...);
|
||||
}
|
||||
}
|
||||
|
||||
template<size_t CstringIdx>
|
||||
static inline constexpr char* encodeArgs(size_t* cstringSize, char* out) {
|
||||
return out;
|
||||
}
|
||||
|
||||
template<size_t CstringIdx, typename Arg, typename... Args>
|
||||
static inline constexpr char* encodeArgs(size_t* cstringSize, char* out, Arg&& arg,
|
||||
Args&&... args) {
|
||||
if constexpr (isNamedArg<Arg>()) {
|
||||
return encodeArgs<CstringIdx>(cstringSize, out, arg.value, std::forward<Args>(args)...);
|
||||
}
|
||||
else if constexpr (isCstring<Arg>()) {
|
||||
memcpy(out, arg, cstringSize[CstringIdx]);
|
||||
return encodeArgs<CstringIdx + 1>(cstringSize, out + cstringSize[CstringIdx],
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
else if constexpr (isString<Arg>()) {
|
||||
size_t len = arg.size();
|
||||
memcpy(out, arg.data(), len);
|
||||
out[len] = 0;
|
||||
return encodeArgs<CstringIdx>(cstringSize, out + len + 1, std::forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
// If Arg has alignment >= 16, gcc could emit aligned move instructions(e.g. movdqa) for
|
||||
// placement new even if the *out* is misaligned, which would cause segfault. So we use memcpy
|
||||
// when possible
|
||||
if constexpr (std::is_trivially_copyable_v<fmt::remove_cvref_t<Arg>>) {
|
||||
memcpy(out, &arg, sizeof(Arg));
|
||||
}
|
||||
else {
|
||||
new (out) fmt::remove_cvref_t<Arg>(std::forward<Arg>(arg));
|
||||
}
|
||||
return encodeArgs<CstringIdx>(cstringSize, out + sizeof(Arg), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template<size_t Idx, size_t NamedIdx>
|
||||
static inline constexpr void storeNamedArgs(fmt::detail::named_arg_info<char>* named_args_store) {
|
||||
}
|
||||
|
||||
template<size_t Idx, size_t NamedIdx, typename Arg, typename... Args>
|
||||
static inline constexpr void storeNamedArgs(fmt::detail::named_arg_info<char>* named_args_store,
|
||||
const Arg& arg, const Args&... args) {
|
||||
if constexpr (isNamedArg<Arg>()) {
|
||||
named_args_store[NamedIdx] = {arg.name, Idx};
|
||||
storeNamedArgs<Idx + 1, NamedIdx + 1>(named_args_store, args...);
|
||||
}
|
||||
else {
|
||||
storeNamedArgs<Idx + 1, NamedIdx>(named_args_store, args...);
|
||||
}
|
||||
}
|
||||
|
||||
template<bool ValueOnly, size_t Idx, size_t DestructIdx>
|
||||
static inline const char* decodeArgs(const char* in, fmt::basic_format_arg<Context>* args,
|
||||
const char** destruct_args) {
|
||||
return in;
|
||||
}
|
||||
|
||||
template<bool ValueOnly, size_t Idx, size_t DestructIdx, typename Arg, typename... Args>
|
||||
static inline const char* decodeArgs(const char* in, fmt::basic_format_arg<Context>* args,
|
||||
const char** destruct_args) {
|
||||
using namespace fmtlogdetail;
|
||||
using ArgType = fmt::remove_cvref_t<Arg>;
|
||||
if constexpr (isNamedArg<ArgType>()) {
|
||||
return decodeArgs<ValueOnly, Idx, DestructIdx, typename unNamedType<ArgType>::type, Args...>(
|
||||
in, args, destruct_args);
|
||||
}
|
||||
else if constexpr (isCstring<Arg>() || isString<Arg>()) {
|
||||
size_t size = strlen(in);
|
||||
fmt::string_view v(in, size);
|
||||
if constexpr (ValueOnly) {
|
||||
fmt::detail::value<Context>& value_ = *(fmt::detail::value<Context>*)(args + Idx);
|
||||
value_ = fmt::detail::arg_mapper<Context>().map(v);
|
||||
}
|
||||
else {
|
||||
args[Idx] = fmt::detail::make_arg<Context>(v);
|
||||
}
|
||||
return decodeArgs<ValueOnly, Idx + 1, DestructIdx, Args...>(in + size + 1, args,
|
||||
destruct_args);
|
||||
}
|
||||
else {
|
||||
if constexpr (ValueOnly) {
|
||||
fmt::detail::value<Context>& value_ = *(fmt::detail::value<Context>*)(args + Idx);
|
||||
if constexpr (UnrefPtr<ArgType>::value) {
|
||||
value_ = fmt::detail::arg_mapper<Context>().map(**(ArgType*)in);
|
||||
}
|
||||
else {
|
||||
value_ = fmt::detail::arg_mapper<Context>().map(*(ArgType*)in);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr (UnrefPtr<ArgType>::value) {
|
||||
args[Idx] = fmt::detail::make_arg<Context>(**(ArgType*)in);
|
||||
}
|
||||
else {
|
||||
args[Idx] = fmt::detail::make_arg<Context>(*(ArgType*)in);
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (needCallDtor<Arg>()) {
|
||||
destruct_args[DestructIdx] = in;
|
||||
return decodeArgs<ValueOnly, Idx + 1, DestructIdx + 1, Args...>(in + sizeof(ArgType), args,
|
||||
destruct_args);
|
||||
}
|
||||
else {
|
||||
return decodeArgs<ValueOnly, Idx + 1, DestructIdx, Args...>(in + sizeof(ArgType), args,
|
||||
destruct_args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<size_t DestructIdx>
|
||||
static inline void destructArgs(const char** destruct_args) {}
|
||||
|
||||
template<size_t DestructIdx, typename Arg, typename... Args>
|
||||
static inline void destructArgs(const char** destruct_args) {
|
||||
using ArgType = fmt::remove_cvref_t<Arg>;
|
||||
if constexpr (isNamedArg<ArgType>()) {
|
||||
destructArgs<DestructIdx, typename unNamedType<ArgType>::type, Args...>(destruct_args);
|
||||
}
|
||||
else if constexpr (needCallDtor<Arg>()) {
|
||||
((ArgType*)destruct_args[DestructIdx])->~ArgType();
|
||||
destructArgs<DestructIdx + 1, Args...>(destruct_args);
|
||||
}
|
||||
else {
|
||||
destructArgs<DestructIdx, Args...>(destruct_args);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
static const char* formatTo(fmt::string_view format, const char* data, MemoryBuffer& out,
|
||||
int& argIdx, std::vector<fmt::basic_format_arg<Context>>& args) {
|
||||
constexpr size_t num_args = sizeof...(Args);
|
||||
constexpr size_t num_dtors = fmt::detail::count<needCallDtor<Args>()...>();
|
||||
const char* dtor_args[(std::max)(num_dtors, (size_t)1)];
|
||||
const char* ret;
|
||||
if (argIdx < 0) {
|
||||
argIdx = (int)args.size();
|
||||
args.resize(argIdx + num_args);
|
||||
ret = decodeArgs<false, 0, 0, Args...>(data, args.data() + argIdx, dtor_args);
|
||||
}
|
||||
else {
|
||||
ret = decodeArgs<true, 0, 0, Args...>(data, args.data() + argIdx, dtor_args);
|
||||
}
|
||||
vformat_to(out, format, fmt::basic_format_args(args.data() + argIdx, num_args));
|
||||
destructArgs<0, Args...>(dtor_args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<bool Reorder, typename... Args>
|
||||
static fmt::string_view unNameFormat(fmt::string_view in, uint32_t* reorderIdx,
|
||||
const Args&... args) {
|
||||
constexpr size_t num_named_args = fmt::detail::count<isNamedArg<Args>()...>();
|
||||
if constexpr (num_named_args == 0) {
|
||||
return in;
|
||||
}
|
||||
const char* begin = in.data();
|
||||
const char* p = begin;
|
||||
std::unique_ptr<char[]> unnamed_str(new char[in.size() + 1 + num_named_args * 5]);
|
||||
fmt::detail::named_arg_info<char> named_args[(std::max)(num_named_args, (size_t)1)];
|
||||
storeNamedArgs<0, 0>(named_args, args...);
|
||||
|
||||
char* out = (char*)unnamed_str.get();
|
||||
uint8_t arg_idx = 0;
|
||||
while (true) {
|
||||
auto c = *p++;
|
||||
if (!c) {
|
||||
size_t copy_size = p - begin - 1;
|
||||
memcpy(out, begin, copy_size);
|
||||
out += copy_size;
|
||||
break;
|
||||
}
|
||||
if (c != '{') continue;
|
||||
size_t copy_size = p - begin;
|
||||
memcpy(out, begin, copy_size);
|
||||
out += copy_size;
|
||||
begin = p;
|
||||
c = *p++;
|
||||
if (!c) fmt::detail::throw_format_error("invalid format string");
|
||||
if (fmt::detail::is_name_start(c)) {
|
||||
while ((fmt::detail::is_name_start(c = *p) || ('0' <= c && c <= '9'))) {
|
||||
++p;
|
||||
}
|
||||
fmt::string_view name(begin, p - begin);
|
||||
int id = -1;
|
||||
for (size_t i = 0; i < num_named_args; ++i) {
|
||||
if (named_args[i].name == name) {
|
||||
id = named_args[i].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (id < 0) fmt::detail::throw_format_error("invalid format string");
|
||||
if constexpr (Reorder) {
|
||||
reorderIdx[id] = arg_idx++;
|
||||
}
|
||||
else {
|
||||
out = fmt::format_to(out, "{}", id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
*out++ = c;
|
||||
}
|
||||
begin = p;
|
||||
}
|
||||
const char* ptr = unnamed_str.release();
|
||||
return fmt::string_view(ptr, out - ptr);
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
inline void log(
|
||||
uint32_t& logId, int64_t tsc, const char* location, LogLevel level,
|
||||
fmt::format_string<typename fmtlogdetail::UnrefPtr<fmt::remove_cvref_t<Args>>::type...> format,
|
||||
Args&&... args) noexcept {
|
||||
if (!logId) {
|
||||
auto unnamed_format = unNameFormat<false>(fmt::string_view(format), nullptr, args...);
|
||||
registerLogInfo(logId, formatTo<Args...>, location, level, unnamed_format);
|
||||
}
|
||||
constexpr size_t num_cstring = fmt::detail::count<isCstring<Args>()...>();
|
||||
size_t cstringSizes[(std::max)(num_cstring, (size_t)1)];
|
||||
uint32_t alloc_size = 8 + (uint32_t)getArgSizes<0>(cstringSizes, args...);
|
||||
bool q_full_cb = true;
|
||||
do {
|
||||
if (auto header = allocMsg(alloc_size, q_full_cb)) {
|
||||
header->logId = logId;
|
||||
char* out = (char*)(header + 1);
|
||||
*(int64_t*)out = tsc;
|
||||
out += 8;
|
||||
encodeArgs<0>(cstringSizes, out, std::forward<Args>(args)...);
|
||||
header->push(alloc_size);
|
||||
break;
|
||||
}
|
||||
q_full_cb = false;
|
||||
} while (FMTLOG_BLOCK);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
inline void logOnce(const char* location, LogLevel level, fmt::format_string<Args...> format,
|
||||
Args&&... args) {
|
||||
fmt::string_view sv(format);
|
||||
auto&& fmt_args = fmt::make_format_args(args...);
|
||||
uint32_t fmt_size = formatted_size(sv, fmt_args);
|
||||
uint32_t alloc_size = 8 + 8 + fmt_size;
|
||||
bool q_full_cb = true;
|
||||
do {
|
||||
if (auto header = allocMsg(alloc_size, q_full_cb)) {
|
||||
header->logId = (uint32_t)level;
|
||||
char* out = (char*)(header + 1);
|
||||
*(int64_t*)out = tscns.rdtsc();
|
||||
out += 8;
|
||||
*(const char**)out = location;
|
||||
out += 8;
|
||||
vformat_to(out, sv, fmt_args);
|
||||
header->push(alloc_size);
|
||||
break;
|
||||
}
|
||||
q_full_cb = false;
|
||||
} while (FMTLOG_BLOCK);
|
||||
}
|
||||
};
|
||||
|
||||
using fmtlog = fmtlogT<>;
|
||||
|
||||
template<int _>
|
||||
FAST_THREAD_LOCAL typename fmtlogT<_>::ThreadBuffer* fmtlogT<_>::threadBuffer;
|
||||
|
||||
template<int __ = 0>
|
||||
struct fmtlogWrapper
|
||||
{ static fmtlog impl; };
|
||||
|
||||
template<int _>
|
||||
fmtlog fmtlogWrapper<_>::impl;
|
||||
|
||||
template<int _>
|
||||
inline void fmtlogT<_>::setLogLevel(LogLevel logLevel) noexcept {
|
||||
fmtlogWrapper<>::impl.currentLogLevel = logLevel;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
inline typename fmtlogT<_>::LogLevel fmtlogT<_>::getLogLevel() noexcept {
|
||||
return fmtlogWrapper<>::impl.currentLogLevel;
|
||||
}
|
||||
|
||||
template<int _>
|
||||
inline bool fmtlogT<_>::checkLogLevel(LogLevel logLevel) noexcept {
|
||||
#ifdef FMTLOG_NO_CHECK_LEVEL
|
||||
return true;
|
||||
#else
|
||||
return logLevel >= fmtlogWrapper<>::impl.currentLogLevel;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define __FMTLOG_S1(x) #x
|
||||
#define __FMTLOG_S2(x) __FMTLOG_S1(x)
|
||||
#define __FMTLOG_LOCATION __FILE__ ":" __FMTLOG_S2(__LINE__)
|
||||
|
||||
#define FMTLOG(level, format, ...) \
|
||||
do { \
|
||||
static uint32_t logId = 0; \
|
||||
if (!fmtlog::checkLogLevel(level)) break; \
|
||||
fmtlogWrapper<>::impl.log(logId, fmtlogWrapper<>::impl.tscns.rdtsc(), __FMTLOG_LOCATION, \
|
||||
level, format, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define FMTLOG_LIMIT(min_interval, level, format, ...) \
|
||||
do { \
|
||||
static uint32_t logId = 0; \
|
||||
static int64_t limitNs = 0; \
|
||||
if (!fmtlog::checkLogLevel(level)) break; \
|
||||
int64_t tsc = fmtlogWrapper<>::impl.tscns.rdtsc(); \
|
||||
int64_t ns = fmtlogWrapper<>::impl.tscns.tsc2ns(tsc); \
|
||||
if (ns < limitNs) break; \
|
||||
limitNs = ns + min_interval; \
|
||||
fmtlogWrapper<>::impl.log(logId, tsc, __FMTLOG_LOCATION, level, format, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define FMTLOG_ONCE(level, format, ...) \
|
||||
do { \
|
||||
if (!fmtlog::checkLogLevel(level)) break; \
|
||||
fmtlogWrapper<>::impl.logOnce(__FMTLOG_LOCATION, level, format, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#if FMTLOG_ACTIVE_LEVEL <= FMTLOG_LEVEL_DBG
|
||||
#define logd(format, ...) FMTLOG(fmtlog::DBG, format, ##__VA_ARGS__)
|
||||
#define logdo(format, ...) FMTLOG_ONCE(fmtlog::DBG, format, ##__VA_ARGS__)
|
||||
#define logdl(min_interval, format, ...) FMTLOG_LIMIT(min_interval, fmtlog::DBG, format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define logd(format, ...) (void)0
|
||||
#define logdo(format, ...) (void)0
|
||||
#define logdl(min_interval, format, ...) (void)0
|
||||
#endif
|
||||
|
||||
#if FMTLOG_ACTIVE_LEVEL <= FMTLOG_LEVEL_INF
|
||||
#define logi(format, ...) FMTLOG(fmtlog::INF, format, ##__VA_ARGS__)
|
||||
#define logio(format, ...) FMTLOG_ONCE(fmtlog::INF, format, ##__VA_ARGS__)
|
||||
#define logil(min_interval, format, ...) FMTLOG_LIMIT(min_interval, fmtlog::INF, format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define logi(format, ...) (void)0
|
||||
#define logio(format, ...) (void)0
|
||||
#define logil(min_interval, format, ...) (void)0
|
||||
#endif
|
||||
|
||||
#if FMTLOG_ACTIVE_LEVEL <= FMTLOG_LEVEL_WRN
|
||||
#define logw(format, ...) FMTLOG(fmtlog::WRN, format, ##__VA_ARGS__)
|
||||
#define logwo(format, ...) FMTLOG_ONCE(fmtlog::WRN, format, ##__VA_ARGS__)
|
||||
#define logwl(min_interval, format, ...) FMTLOG_LIMIT(min_interval, fmtlog::WRN, format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define logw(format, ...) (void)0
|
||||
#define logwo(format, ...) (void)0
|
||||
#define logwl(min_interval, format, ...) (void)0
|
||||
#endif
|
||||
|
||||
#if FMTLOG_ACTIVE_LEVEL <= FMTLOG_LEVEL_ERR
|
||||
#define loge(format, ...) FMTLOG(fmtlog::ERR, format, ##__VA_ARGS__)
|
||||
#define logeo(format, ...) FMTLOG_ONCE(fmtlog::ERR, format, ##__VA_ARGS__)
|
||||
#define logel(min_interval, format, ...) FMTLOG_LIMIT(min_interval, fmtlog::ERR, format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define loge(format, ...) (void)0
|
||||
#define logeo(format, ...) (void)0
|
||||
#define logel(min_interval, format, ...) (void)0
|
||||
#endif
|
||||
|
||||
#ifdef FMTLOG_HEADER_ONLY
|
||||
#include "fmtlog-inl.h"
|
||||
#endif
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
//#ifdef __cplusplus
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
//#else
|
||||
//#define ARRAY_SIZE_TYPE_CHECK(a) (sizeof(typeof(int[1 - 2 * !!__builtin_types_compatible_p(typeof(a), typeof(&a[0]))])))
|
||||
//#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]) + ARRAY_SIZE_TYPE_CHECK(a) * 0)
|
||||
//#endif
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="vcpkg.C.llvmmingw20230517ucrtx8664.vcpkg" version="1.0.0" targetFramework="native" />
|
||||
</packages>
|
|
@ -0,0 +1,5 @@
|
|||
// pch.cpp: 与预编译标头对应的源文件
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
|
|
@ -0,0 +1,13 @@
|
|||
// pch.h: 这是预编译标头文件。
|
||||
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
|
||||
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
|
||||
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
|
||||
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
// 添加要在此处预编译的标头
|
||||
#include "framework.h"
|
||||
|
||||
#endif //PCH_H
|
|
@ -0,0 +1,80 @@
|
|||
#include "pch.h"
|
||||
#include "tunnel.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "usrerr.h"
|
||||
#include "logs/fmtlog.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PROTO_CRYPTO_TYPE proCryptoType;
|
||||
char proKeyBuf[CRYPTO_MAX][256];
|
||||
} SDK_CONFIG, *PSDK_CONFIG;
|
||||
|
||||
static SDK_CONFIG g_globalConfig;
|
||||
|
||||
NETTUNNELSDK_API int TunnelSDKInitEnv()
|
||||
{
|
||||
memset(&g_globalConfig, 0, sizeof(SDK_CONFIG));
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
NETTUNNELSDK_API void InitTunnelSDKLog(const char* pLogFile, LOG_LEVEL level)
|
||||
{
|
||||
char buf[MAX_PATH] = {0};
|
||||
static fmtlog::LogLevel lv[LOG_MAX] = {fmtlog::DBG, fmtlog::INF, fmtlog::WRN, fmtlog::ERR,};
|
||||
|
||||
//::MessageBoxA(NULL, pLogFile, NULL, MB_OK);
|
||||
if (pLogFile && strlen(pLogFile) > 0)
|
||||
{
|
||||
strncpy_s(buf, pLogFile, MAX_PATH);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetCurrentDirectory(MAX_PATH, buf);
|
||||
strcat_s(buf, "\\tunnelsdk.log");
|
||||
}
|
||||
|
||||
fmtlog::setLogFile(buf, false);
|
||||
fmtlog::setHeaderPattern("[{YmdHMSe}][{l}][{s}] ");
|
||||
fmtlog::setFlushDelay(1000000);
|
||||
fmtlog::setLogLevel(lv[level]);
|
||||
|
||||
FMTLOG(lv[level], "Log({1}):{0}", buf, (int)level);
|
||||
}
|
||||
|
||||
|
||||
NETTUNNELSDK_API int SetProtocolEncryptType(PROTO_CRYPTO_TYPE type, const char* pProKey)
|
||||
{
|
||||
if (type > CRYPTO_BASE64)
|
||||
{
|
||||
if (pProKey == nullptr || strlen(pProKey) < 8)
|
||||
{
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
}
|
||||
|
||||
g_globalConfig.proCryptoType = type;
|
||||
strncpy_s(g_globalConfig.proKeyBuf[type], pProKey, 256);
|
||||
|
||||
logd("Protocol crypto type: {0} with key [{1}]", (int)type, pProKey? pProKey : "");
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
NETTUNNELSDK_API int CreateTunnel(LPCSTR lpszMsg)
|
||||
{
|
||||
OutputDebugStringA(lpszMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NETTUNNELSDK_API const char* TestMessage()
|
||||
{
|
||||
return "Test Message";
|
||||
}
|
||||
|
||||
NETTUNNELSDK_API int Add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#ifdef NETTUNNELSDK_EXPORTS
|
||||
#define NETTUNNELSDK_API __declspec(dllexport)
|
||||
#else
|
||||
#define NETTUNNELSDK_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
using PROTO_CRYPTO_TYPE = enum
|
||||
{
|
||||
CRYPTO_NONE = 0,
|
||||
CRYPTO_BASE64 = 1,
|
||||
CRYPTO_AES128 = 2,
|
||||
CRYPTO_3DES = 3,
|
||||
CRYPTO_AES256 = 4,
|
||||
CRYPTO_MAX,
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LOG_DEBUG = 0,
|
||||
LOG_INFO = 1,
|
||||
LOG_WARN = 2,
|
||||
LOG_ERROR = 3,
|
||||
LOG_MAX
|
||||
} LOG_LEVEL;
|
||||
|
||||
#ifdef __cplusplus // If used by C++ code,
|
||||
extern "C" {
|
||||
// we need to export the C interface
|
||||
#endif
|
||||
|
||||
NETTUNNELSDK_API int __cdecl CreateTunnel(LPCSTR lpszMsg);
|
||||
NETTUNNELSDK_API const char*__cdecl TestMessage();
|
||||
NETTUNNELSDK_API int __cdecl Add(int a, int b);
|
||||
NETTUNNELSDK_API int __cdecl TunnelSDKInitEnv();
|
||||
NETTUNNELSDK_API int __cdecl SetProtocolEncryptType(PROTO_CRYPTO_TYPE type, const char* pProKey);
|
||||
NETTUNNELSDK_API void __cdecl InitTunnelSDKLog(const char* pLogFile, LOG_LEVEL level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
#include "usrerr.h"
|
||||
#include "misc.h"
|
||||
|
||||
#define MAX_DESC_LENGTH (256)
|
||||
#define GENERATE_STRING(STRING,x, desc) {#STRING, desc},
|
||||
|
||||
|
||||
static const char *g_enumStrVal[][MAX_DESC_LENGTH] = {
|
||||
DEF_ERR_CODE(GENERATE_STRING) {"ERR_UNKNOWN", "未知错误"},
|
||||
};
|
||||
|
||||
const char *getErrorEnumNameString(int errCode) {
|
||||
if (errCode < 0) {
|
||||
errCode = -errCode;
|
||||
}
|
||||
|
||||
if (errCode >= ARRAY_SIZE(g_enumStrVal) || errCode < 0) {
|
||||
return g_enumStrVal[ARRAY_SIZE(g_enumStrVal) - 1][0];
|
||||
}
|
||||
return g_enumStrVal[errCode][0];
|
||||
}
|
||||
|
||||
const char *getErrorEnumDesc(int errCode) {
|
||||
if (errCode >= ARRAY_SIZE(g_enumStrVal) || errCode < 0) {
|
||||
return g_enumStrVal[ARRAY_SIZE(g_enumStrVal) - 1][0];
|
||||
}
|
||||
return g_enumStrVal[errCode][1];
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#define DEF_ERR_CODE(ERR_CODE) \
|
||||
ERR_CODE(ERR_SUCCESS, 0, "成功") \
|
||||
ERR_CODE(ERR_INPUT_PARAMS, 1, "输入参数错误") \
|
||||
ERR_CODE(ERR_UN_SUPPORT, 2, "不支持的操作") \
|
||||
ERR_CODE(ERR_CALL_SHELL, 3, "调用Shell命令失败") \
|
||||
ERR_CODE(ERR_ITEM_EXISTS, 4, "该内容已经存在") \
|
||||
ERR_CODE(ERR_ITEM_UNEXISTS, 5, "该内容不存在") \
|
||||
ERR_CODE(ERR_SYS_INIT, 6, "系统中断") \
|
||||
ERR_CODE(ERR_SYS_CALL, 7, "系统调用") \
|
||||
ERR_CODE(ERR_OPEN_FILE, 8, "打开文件失败") \
|
||||
ERR_CODE(ERR_READ_FILE, 9, "读取文件失败") \
|
||||
ERR_CODE(ERR_FILE_NOT_EXISTS, 10, "文件不存在") \
|
||||
ERR_CODE(ERR_FILE_LOCKED, 11, "文件被锁定") \
|
||||
ERR_CODE(ERR_GET_FILE_SIZE, 12, "获取文件大小失败") \
|
||||
ERR_CODE(ERR_COPY_FILE, 13, "复制文件失败") \
|
||||
ERR_CODE(ERR_MALLOC_MEMORY, 14, "分配内存失败") \
|
||||
ERR_CODE(ERR_MMAP_MEMORY, 15, "共享内存失败")
|
||||
|
||||
#define GENERATE_ENUM(ENUM, n, x) ENUM,
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DEF_ERR_CODE(GENERATE_ENUM)
|
||||
} USER_ERRNO;
|
|
@ -0,0 +1,100 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.33627.172
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetTunnelSDK", "NetTunnelSDK\NetTunnelSDK.vcxproj", "{42AACC62-A37C-4B33-A687-D13C472CC980}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetTunnelApp", "NetTunnelApp\NetTunnelApp.csproj", "{4999B360-F561-4B6D-A7B0-82EECE329089}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980} = {42AACC62-A37C-4B33-A687-D13C472CC980}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UTNetTunnelSDK", "UTNetTunnelSDK\UTNetTunnelSDK.vcxproj", "{6E425E69-15FA-474A-8798-054F0E0005E1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetTunnelDemo", "NetTunnelDemo\NetTunnelDemo.vcxproj", "{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM64 = Release|ARM64
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Debug|ARM64.ActiveCfg = Debug|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Debug|ARM64.Build.0 = Debug|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Debug|x64.Build.0 = Debug|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Debug|x86.Build.0 = Debug|Win32
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Release|Any CPU.Build.0 = Release|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Release|ARM64.ActiveCfg = Release|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Release|ARM64.Build.0 = Release|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Release|x64.ActiveCfg = Release|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Release|x64.Build.0 = Release|x64
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Release|x86.ActiveCfg = Release|Win32
|
||||
{42AACC62-A37C-4B33-A687-D13C472CC980}.Release|x86.Build.0 = Release|Win32
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Release|ARM64.Build.0 = Release|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4999B360-F561-4B6D-A7B0-82EECE329089}.Release|x86.Build.0 = Release|Any CPU
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Debug|ARM64.ActiveCfg = Debug|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Debug|ARM64.Build.0 = Debug|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Debug|x64.Build.0 = Debug|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Release|Any CPU.Build.0 = Release|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Release|ARM64.ActiveCfg = Release|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Release|ARM64.Build.0 = Release|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Release|x64.ActiveCfg = Release|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Release|x64.Build.0 = Release|x64
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6E425E69-15FA-474A-8798-054F0E0005E1}.Release|x86.Build.0 = Release|Win32
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Debug|ARM64.ActiveCfg = Debug|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Debug|ARM64.Build.0 = Debug|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Debug|x64.Build.0 = Debug|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Debug|x86.Build.0 = Debug|Win32
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Release|Any CPU.Build.0 = Release|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Release|ARM64.ActiveCfg = Release|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Release|ARM64.Build.0 = Release|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Release|x64.ActiveCfg = Release|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Release|x64.Build.0 = Release|x64
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Release|x86.ActiveCfg = Release|Win32
|
||||
{7CCA5020-1E98-4AEF-99A4-34C05592CFE1}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F2DF1495-C7F9-4EBF-8EDA-C16C5812616A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,18 @@
|
|||
#include "pch.h"
|
||||
#include "CppUnitTest.h"
|
||||
#include "../NetTunnelSDK/tunnel.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace UTNetTunnelSDK {
|
||||
TEST_CLASS(UTNetTunnelSDK) {
|
||||
public:
|
||||
TEST_METHOD(TestTestMessage) {
|
||||
Assert::AreEqual("Test Message", TestMessage());
|
||||
}
|
||||
|
||||
TEST_METHOD(TestTunnelSDKInitEnv) {
|
||||
Assert::AreEqual(0, TunnelSDKInitEnv());
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<ProjectGuid>{6E425E69-15FA-474A-8798-054F0E0005E1}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>UTNetTunnelSDK</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectSubType>NativeUnitTestProject</ProjectSubType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UTNetTunnelSDK.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NetTunnelSDK\NetTunnelSDK.vcxproj">
|
||||
<Project>{42aacc62-a37c-4b33-a687-d13c472cc980}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="UTNetTunnelSDK.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
|
@ -0,0 +1,5 @@
|
|||
// pch.cpp: 与预编译标头对应的源文件
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
|
|
@ -0,0 +1,12 @@
|
|||
// pch.h: 这是预编译标头文件。
|
||||
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
|
||||
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
|
||||
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
|
||||
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
// 添加要在此处预编译的标头
|
||||
|
||||
#endif //PCH_H
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VCPkgLocalAppDataDisabled>true</VCPkgLocalAppDataDisabled>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="C:\llvm-mingw-20230517-ucrt-x86_64\vcpkg\scripts\buildsystems\msbuild\vcpkg.targets" Condition="Exists('C:\llvm-mingw-20230517-ucrt-x86_64\vcpkg\scripts\buildsystems\msbuild\vcpkg.targets')" />
|
||||
<Target Name="CheckValidPlatform" BeforeTargets="Build">
|
||||
<Error Text="Unsupported architecture combination. Remove the 'vcpkg' nuget package." Condition="'$(VCPkgEnabled)' != 'true' and '$(VCPkgDisableError)' == ''"/>
|
||||
</Target>
|
||||
</Project>
|
Binary file not shown.
Loading…
Reference in New Issue